| 
						
						
							
								
							
						
						
					 | 
				
			
			 | 
			 | 
			
				@ -118,6 +118,7 @@ def GetNodeNamedAttributeText(node, node_name, attribute_name):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				class Error(Exception):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  """gclient exception class."""
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  # TODO(maruel): Merge with CheckCallError.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  pass
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
			
			 | 
			 | 
			
				@ -251,54 +252,56 @@ def RemoveDirectory(*path):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    os.rmdir(file_path)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				def SubprocessCall(args, **kwargs):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  """Wraps SubprocessCallAndFilter() with different default arguments.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				def CheckCallAndFilterAndHeader(args, always=False, **kwargs):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  """Adds 'header' support to CheckCallAndFilter.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  Calls subprocess and capture nothing."""
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  kwargs['print_messages'] = True
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  If |always| is True, a message indicating what is being done
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  is printed to stdout all the time even if not output is generated. Otherwise
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  the message header is printed only if the call generated any ouput.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  """
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  stdout = kwargs.get('stdout', None) or sys.stdout
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  if always:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    stdout.write('\n________ running \'%s\' in \'%s\'\n'
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        % (' '.join(args), kwargs.get('cwd', '.')))
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  else:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    filter_fn = kwargs.get('filter_fn', None)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    def filter_msg(line):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      if line is None:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        stdout.write('\n________ running \'%s\' in \'%s\'\n'
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            % (' '.join(args), kwargs.get('cwd', '.')))
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      elif filter_fn:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        filter_fn(line)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    kwargs['filter_fn'] = filter_msg
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    kwargs['call_filter_on_first_line'] = True
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  # Obviously.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  kwargs['print_stdout'] = True
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  return SubprocessCallAndFilter(args, **kwargs)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				def SubprocessCallAndFilter(args, **kwargs):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  """Runs a command and prints a header line if appropriate.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  return CheckCallAndFilter(args, **kwargs)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  If |print_messages| is True, a message indicating what is being done
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  is printed to stdout. Otherwise the message is printed only if the call
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  generated any ouput. If both |print_messages| and |print_stdout| are False,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  no output at all is generated.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  If |print_stdout| is True, the command's stdout is also forwarded to stdout.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				def CheckCallAndFilter(args, stdout=None, filter_fn=None,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                       print_stdout=None, call_filter_on_first_line=False,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                       **kwargs):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  """Runs a command and calls back a filter function if needed.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  If |filter_fn| function is specified, it is expected to take a single
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  string argument, and it will be called with each line of the
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  subprocess's output. Each line has had the trailing newline character
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  trimmed.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  Accepts all subprocess.Popen() parameters plus:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    print_stdout: If True, the command's stdout is forwarded to stdout.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    filter_fn: A function taking a single string argument called with each line
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				               of the subprocess's output. Each line has the trailing newline
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				               character trimmed.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    stdout: Can be any bufferable output.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  If the command fails, as indicated by a nonzero exit status, gclient will
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  exit with an exit status of fail_status. If fail_status is None (the
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  default), gclient will raise an Error exception.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  Other subprocess.Popen parameters can be specified.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  stderr is always redirected to stdout.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  """
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  stdout = kwargs.pop('stdout', sys.stdout) or sys.stdout
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  assert print_stdout or filter_fn
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  stdout = stdout or sys.stdout
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  filter_fn = filter_fn or (lambda x: None)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  assert not 'stderr' in kwargs
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  filter_fn = kwargs.pop('filter_fn', None)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  print_messages = kwargs.pop('print_messages', False)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  print_stdout = kwargs.pop('print_stdout', False)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  fail_status = kwargs.pop('fail_status', None)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  logging.debug(args)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  if print_messages:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    stdout.write('\n________ running \'%s\' in \'%s\'\n'
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				          % (' '.join(args), kwargs['cwd']))
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  kid = Popen(args, bufsize=0,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				              stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				              **kwargs)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  # Do a flush of sys.stdout before we begin reading from the subprocess's
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  # stdout.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  # Do a flush of stdout before we begin reading from the subprocess's stdout
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  last_flushed_at = time.time()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  stdout.flush()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
			
			 | 
			 | 
			
				@ -307,40 +310,34 @@ def SubprocessCallAndFilter(args, **kwargs):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  # normally buffering is done for each line, but if svn requests input, no
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  # end-of-line character is output after the prompt and it would not show up.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  in_byte = kid.stdout.read(1)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  in_line = ''
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  while in_byte:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    if in_byte != '\r':
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      if print_stdout:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        if not print_messages:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				          stdout.write('\n________ running \'%s\' in \'%s\'\n'
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				              % (' '.join(args), kwargs['cwd']))
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				          print_messages = True
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        stdout.write(in_byte)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      if in_byte != '\n':
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        in_line += in_byte
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    if in_byte == '\n':
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      if filter_fn:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        filter_fn(in_line)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      in_line = ''
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      # Flush at least 10 seconds between line writes.  We wait at least 10
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      # seconds to avoid overloading the reader that called us with output,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      # which can slow busy readers down.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      if (time.time() - last_flushed_at) > 10:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        last_flushed_at = time.time()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        stdout.flush()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    in_byte = kid.stdout.read(1)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  # Flush the rest of buffered output. This is only an issue with files not
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  # ending with a \n.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  if len(in_line) and filter_fn:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    filter_fn(in_line)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  if in_byte:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    if call_filter_on_first_line:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      filter_fn(None)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    in_line = ''
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    while in_byte:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      if in_byte != '\r':
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        if print_stdout:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				          stdout.write(in_byte)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        if in_byte != '\n':
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				          in_line += in_byte
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        else:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				          filter_fn(in_line)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				          in_line = ''
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				          # Flush at least 10 seconds between line writes.  We wait at least 10
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				          # seconds to avoid overloading the reader that called us with output,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				          # which can slow busy readers down.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				          if (time.time() - last_flushed_at) > 10:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            last_flushed_at = time.time()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            stdout.flush()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      in_byte = kid.stdout.read(1)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    # Flush the rest of buffered output. This is only an issue with
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    # stdout/stderr not ending with a \n.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    if len(in_line):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      filter_fn(in_line)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  rv = kid.wait()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  if rv:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    msg = 'failed to run command: %s' % ' '.join(args)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    if fail_status != None:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      sys.stderr.write(msg + '\n')
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      sys.exit(fail_status)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    raise Error(msg)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    raise Error('failed to run command: %s' % ' '.join(args))
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  return 0
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				def FindGclientRoot(from_dir, filename='.gclient'):
 | 
			
		
		
	
	
		
			
				
					| 
						
							
								
							
						
						
						
					 | 
				
			
			 | 
			 | 
			
				
 
 |