Commit fb2b8eb2 authored by maruel@google.com's avatar maruel@google.com

Create the Next Generation of depot_tools. Eh.

Review URL: http://codereview.chromium.org/92087

git-svn-id: svn://svn.chromium.org/chrome/trunk/tools/depot_tools@14349 0039d316-1c4b-4281-b951-d872f2087c98
parents
// Copyright (c) 2009 The Chromium Authors. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
This package contains tools for working with Chromium development.
The "gclient" wrapper knows how to keep this repository updated to
the latest versions of these tools as found at:
http://src.chromium.org/svn/trunk/tools/depot_tools
This package contains:
chrome-update-create-task.bat
Creates a scheduled task to do an automatic local chromium build every day.
gcl
A tool for uploading and managing code reviews on the Chromium
project, using the Rietveld code review tool. More info at:
http://code.google.com/p/rietveld/
gclient
A script for managing a workspace with modular dependencies that
are each checked out independently from different repositories.
More info at:
http://code.google.com/p/gclient/
hammer
A wrapper script for building Chromium with the SCons software
construction tool. More info at:
http://www.scons.org/
revert
A small tool to quickly revert a change.
Note: svn and python will be installed automatically if not accessible (on
Windows only).
To update this distribution manually, run bootstrap\update.bat on Windows,
or bootstrap/update.sh on Linux or Mac.
To disable automatic updating, set the environment variable DEPOT_TOOLS_UPDATE=1
\ No newline at end of file
# git-cl -- a git-command for integrating reviews on Rietveld
# Copyright (C) 2008 Evan Martin <martine@danga.com>
== Background
Rietveld, also known as http://codereview.appspot.com, is a nice tool
for code reviews. You upload a patch (and some other data) and it lets
others comment on your patch.
For more on how this all works conceptually, please see README.codereview.
The remainder of this document is the nuts and bolts of using git-cl.
== Install
Copy (symlink) it into your path somewhere, along with Rietveld
upload.py.
== Setup
Run this from your git checkout and answer some questions:
$ git cl config
== How to use it
Make a new branch. Write some code. Commit it locally. Send it for
review:
$ git cl upload
By default, it diffs against whatever branch the current branch is
tracking (see "git checkout --track"). An optional last argument is
passed to "git diff", allowing reviews against other heads.
You'll be asked some questions, and the review issue number will be
associated with your current git branch, so subsequent calls to upload
will update that review rather than making a new one.
== git-svn integration
Review looks good? Commit the code:
$ git cl dcommit
This does a git-svn dcommit, with a twist: all changes in the diff
will be squashed into a single commit, and the description of the commit
is taken directly from the Rietveld description. This command also accepts
arguments to "git diff", much like upload.
Try "git cl dcommit --help" for more options.
== Extra commands
Print some status info:
$ git cl status
Edit the issue association on the current branch:
$ git cl issue 1234
Patch in a review:
$ git cl patch <url to full patch>
Try "git cl patch --help" for more options.
vim: tw=72 :
The git-cl README describes the git-cl command set. This document
describes how code review and git work together in general, intended
for people familiar with git but unfamiliar with the code review
process supported by Rietveld.
== Concepts and terms
A Rietveld review is for discussion of a single change or patch. You
upload a proposed change, the reviewer comments on your change, and
then you can upload a revised version of your change. Rietveld stores
the history of uploaded patches as well as the comments, and can
compute diffs in between these patches. The history of a patch is
very much like a small branch in git, but since Rietveld is
VCS-agnostic the concepts don't map perfectly. The identifier for a
single review+patches+comments in Rietveld is called an "issue".
Rietveld provides a basic uploader that understands git. This program
is used by git-cl, and is included in the git-cl repo as upload.py.
== Basic interaction with git
The fundamental problem you encounter when you try to mix git and code
review is that with git it's nice to commit code locally, while during
a code review you're often requested to change something about your
code. There are a few different ways you can handle this workflow
with git:
1) Rewriting a single commit. Say the origin commit is O, and you
commit your initial work in a commit A, making your history like
O--A. After review comments, you commit --amend, effectively
erasing A and making a new commit A', so history is now O--A'.
(Equivalently, you can use git reset --soft or git rebase -i.)
2) Writing follow-up commits. Initial work is again in A, and after
review comments, you write a new commit B so your history looks
like O--A--B. When you upload the revised patch, you upload the
diff of O..B, not A..B; you always upload the full diff of what
you're proposing to change.
The Rietveld patch uploader just takes arguments to "git diff", so
either of the above workflows work fine. If all you want to do is
upload a patch, you can use the upload.py provided by Rietveld with
arguments like this:
upload.py --server server.com <args to "git diff">
The first time you upload, it creates a new issue; for follow-ups on
the same issue, you need to provide the issue number:
upload.py --server server.com --issue 1234 <args to "git diff">
== git-cl to the rescue
git-cl simplifies the above in the following ways:
1) "git cl config" puts a persistent --server setting in your .git/config.
2) The first time you upload an issue, the issue number is associated with
the current *branch*. If you upload again, it will upload on the same
issue. (Note that this association is tied to a branch, not a commit,
which means you need a separate branch per review.)
3) If your branch is "tracking" (in the "git checkout --track" sense)
another one (like origin/master), calls to "git cl upload" will
diff against that branch by default. (You can still pass arguments
to "git diff" on the command line, if necessary.)
In the common case, this means that calling simply "git cl upload"
will always upload the correct diff to the correct place.
== Patch series
The above is all you need to know for working on a single patch.
Things get much more complicated when you have a series of commits
that you want to get reviewed. Say your history looks like
O--A--B--C. If you want to upload that as a single review, everything
works just as above.
But what if you upload each of A, B, and C as separate reviews?
What if you then need to change A?
1) One option is rewriting history: write a new commit A', then use
git rebase -i to insert that diff in as O--A--A'--B--C as well as
squash it. This is sometimes not possible if B and C have touched
some lines affected by A'.
2) Another option, and the one espoused by software like topgit, is for
you to have separate branches for A, B, and C, and after writing A'
you merge it into each of those branches. (topgit automates this
merging process.) This is also what is recommended by git-cl, which
likes having different branch identifiers to hang the issue number
off of. Your history ends up looking like:
O---A---B---C
\ \ \
A'--B'--C'
Which is ugly, but it accurately tracks the real history of your work, can
be thrown away at the end by committing A+A' as a single "squash" commit.
In practice, this comes up pretty rarely. Suggestions for better workflows
are welcome.
@echo off
:: Copyright (c) 2009 The Chromium Authors. All rights reserved.
:: Use of this source code is governed by a BSD-style license that can be
:: found in the LICENSE file.
:: This batch file will try to sync the root directory and call back gclient.
setlocal
:: Shall skip automatic update?
IF "%DEPOT_TOOLS_UPDATE%" == "0" GOTO gclient
:: We can't sync if ..\.svn\. doesn't exist.
IF NOT EXIST "%~dp0..\.svn" GOTO gclient
:: Sync the .. directory to update the bootstrap at the same time.
call svn -q up "%~dp0.."
:gclient
:: Defer control.
python "%~dp0\..\gclient.py" %*
#!/bin/sh
# Copyright (c) 2009 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
# This script will try to sync the root and bootstrap directories.
base_dir=$(dirname "$0")
# Skip if $DEPOT_TOOLS_UPDATE==0 or ../.svn/. doesn't exist.
if [ "X$DEPOT_TOOLS_UPDATE" != "X0" -a -e "$base_dir/../.svn" ]
then
# Update the root directory.
svn -q up "$base_dir/.."
fi
exec python "$base_dir/../gclient.py" "$@"
This diff is collapsed.
7-Zip Command line version
~~~~~~~~~~~~~~~~~~~~~~~~~~
License for use and distribution
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
7-Zip Copyright (C) 1999-2009 Igor Pavlov.
7za.exe is distributed under the GNU LGPL license
Notes:
You can use 7-Zip on any computer, including a computer in a commercial
organization. You don't need to register or pay for 7-Zip.
GNU LGPL information
--------------------
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
7-Zip Command line version 4.65
-------------------------------
7-Zip is a file archiver with high compression ratio.
7za.exe is a standalone command line version of 7-Zip.
7-Zip Copyright (C) 1999-2009 Igor Pavlov.
Features of 7za.exe:
- High compression ratio in new 7z format
- Supported formats:
- Packing / unpacking: 7z, ZIP, GZIP, BZIP2 and TAR
- Unpacking only: Z
- Highest compression ratio for ZIP and GZIP formats.
- Fast compression and decompression
- Strong AES-256 encryption in 7z and ZIP formats.
7za.exe is a free software distributed under the GNU LGPL.
Read license.txt for more information.
Source code of 7za.exe and 7-Zip can be found at
http://www.7-zip.org/
7za.exe can work in Windows 95/98/ME/NT/2000/XP/2003/Vista.
There is also port of 7za.exe for POSIX systems like Unix (Linux, Solaris, OpenBSD,
FreeBSD, Cygwin, AIX, ...), MacOS X and BeOS:
http://p7zip.sourceforge.net/
This distributive packet contains the following files:
7za.exe - 7-Zip standalone command line version.
readme.txt - This file.
copying.txt - GNU LGPL license.
license.txt - License information.
7-zip.chm - User's Manual in HTML Help format.
---
End of document
Including the following third parties:
7zip version 4.65
7za.exe is a free software distributed under the GNU LGPL.
Read license.txt for more information.
Source code of 7za.exe and 7-Zip can be found at
http://www.7-zip.org/
Note: packed with UPX to reduce code size.
wget 1.11.4 from http://www.gnu.org/software/wget/
Note: local compile without openssl support to reduce code size.
Note: packed with UPX to reduce code size.
@"%~dp0python\python.exe" %*
@"%~dp0svn\svn.exe" %*
@echo off
:: Copyright (c) 2009 The Chromium Authors. All rights reserved.
:: Use of this source code is governed by a BSD-style license that can be
:: found in the LICENSE file.
:: This script will try to find if svn and python are accessible and it not,
:: it will try to download it and 'install' it in depot_tools.
SETLOCAL
set ROOT_URL=http://src.chromium.org/svn/trunk/tools
set ROOT_DIR=%~dp0..\..
:: If the batch file exists, skip the svn check.
if exist "%ROOT_DIR%\svn.bat" goto :PYTHON
call svn --version 2>nul 1>nul
if errorlevel 1 call :C_SVN
:PYTHON
:: If the batch file exists, skip the python check.
if exist "%ROOT_DIR%\python.bat" goto :EOF
call python --version 2>nul 1>nul
if errorlevel 1 call :C_PYTHON
:: We are done.
goto :EOF
:C_SVN
echo Installing subversion ...
:: svn is not accessible; check it out and create 'proxy' files.
call "%~dp0wget" -q %ROOT_URL%/third_party/svn.7z -O "%~dp0svn.7z"
if errorlevel 1 goto :SVN_FAIL
call "%~dp07za" x "%~dp0svn.7z" %ROOT_DIR%
if errorlevel 1 goto :SVN_FAIL
del "%~dp0svn.7z"
:: Create the batch file.
copy "%~dp0svn.bat" "%ROOT_DIR%"
goto :EOF
:SVN_FAIL
echo Failed to checkout svn automatically.
echo Please visit http://subversion.tigris.org to download the latest subversion client
echo before continuing.
echo You can also get the "prebacked" version used at %ROOT_URL%/third_party/
:: Still try python.
goto :C_PYTHON
:C_PYTHON
echo Installing python ...
call svn co %ROOT_URL%/third_party/python "%ROOT_DIR%\python"
if errorlevel 1 goto :PYTHON_FAIL
:: Create the batch file.
copy "%~dp0python.bat" "%ROOT_DIR%"
goto :EOF
:PYTHON_FAIL
echo Failed to checkout python automatically.
echo Please visit http://python.org to download the latest python 2.x client before
echo continuing.
echo You can also get the "prebacked" version used at %ROOT_URL%/third_party/
goto :EOF
@echo off
:: Copyright (c) 2009 The Chromium Authors. All rights reserved.
:: Use of this source code is governed by a BSD-style license that can be
:: found in the LICENSE file.
setlocal
:: This script will create a scheduled task to run chrome-update every day
:: at the time you specify. This script expects to be live in
:: depot_tools\latest.
::
:: Usage: this-script <time to run task> <path to chrome trunk>
set Out=%USERPROFILE%\chrome-update-task.bat
set TaskTime=%1
set Trunk=%~f2
if not exist "%Trunk%" (
echo Usage: %~n0 ^<time^> ^<c:\path\to\chrome\trunk^>
echo ^<time^> is the time in HH:MM:SS format at which to run the task.
echo Example: %~n0 02:00:00 c:\src\chrome\trunk
exit 1
)
if not exist "%Out%" goto CreateScript
echo WARNING: %Out% already exists.
set Choice=
set /P Choice=Overwrite file [Y/N]?
if not "%Choice%"=="y" goto CreateTask
:CreateScript
echo.
echo Creating %Out%
echo>"%Out%" @echo off
echo>>"%Out%" call "%~dp0\bootstrap\update.bat"
echo>>"%Out%" "%~dp0\chrome-update.bat" "%Trunk%" ^> "%Trunk%\chrome-update-results.txt"
:CreateTask
echo.
echo ***********************************************************************
echo Creating a Scheduled Task to run chrome-update each day at %TaskTime%.
echo The batch file being run will live at %Out%.
echo.
echo WARNING: The password you enter will be displayed in cleartext.
echo If you're paranoid, you can enter blank here and then fix the password
echo by editing the scheduled task manually from the Control Panel.
echo ***********************************************************************
echo.
schtasks /create /tn chrome-update /tr "\"%Out%\"" /sc daily /st %TaskTime%
@echo off
:: This batch file assumes that the correct version of python can be found in
:: the current directory, and that you have Visual Studio 8 installed in the
:: default location.
setlocal
call vcvars32.bat
python "%~dp0chrome-update.py" %*
#!/usr/bin/python
# Copyright (c) 2009 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
# Author: mpcomplete
#
# This script updates and does a clean build of chrome for you.
# Usage: python chrome-update.py C:\path\to\chrome\trunk
#
# It assumes the following:
# - You have gclient.bat and devenv.com in your path (use the wrapper batch
# file to ensure this).
import sys
import os
import subprocess
import httplib
import re
import shutil
import optparse
def Message(str):
"""Prints a status message."""
print "[chrome-update]", str
def FixupPath(path):
"""Returns the OS-ified version of a windows path."""
return os.path.sep.join(path.split("\\"))
def GetRevision():
"""Returns the revision number of the last build that was archived, or
None on failure."""
HOST = "build.chromium.org"
PATH = "/buildbot/continuous/LATEST/REVISION"
EXPR = r"(\d+)"
connection = httplib.HTTPConnection(HOST)
connection.request("GET", PATH)
response = connection.getresponse()
text = response.read()
match = re.search(EXPR, text)
if match:
return int(match.group(1))
return None
def SetRevisionForUpdate(chrome_root):
"""Prepares environment so gclient syncs to a good revision, if possible."""
# Find a buildable revision.
rev = GetRevision()
if rev == None:
Message("WARNING: Failed to find a buildable revision. Syncing to trunk.")
return "trunk"
# Read the .gclient file.
gclient_file = chrome_root + FixupPath("\\.gclient")
if not os.path.exists(gclient_file):
Message("WARNING: Failed to find .gclient file. Syncing to trunk.")
return "trunk"
scope = {}
execfile(gclient_file, scope)
solutions = scope["solutions"]
# Edit the url of the chrome 'src' solution, unless the user wants a
# specific revision.
for solution in solutions:
if solution["name"] == "src":
splitter = solution["url"].split("@")
if len(splitter) == 1:
solution["url"] = splitter[0] + "@" + str(rev)
else:
rev = int(splitter[1])
break
# Write out the new .gclient file.
gclient_override = gclient_file + "-update-chrome"
f = open(gclient_override, "w")
f.write("solutions = " + str(solutions))
f.close()
# Set the env var that the gclient tool looks for.
os.environ["GCLIENT_FILE"] = gclient_override
return rev
def DoUpdate(chrome_root):
"""gclient sync to the latest build."""
# gclient sync
rev = SetRevisionForUpdate(chrome_root)
cmd = ["gclient.bat", "sync"]
Message("Updating to %s: %s" % (rev, cmd))
sys.stdout.flush()
return subprocess.call(cmd, cwd=chrome_root)
def DoClean(chrome_root, type):
"""Clean our build dir."""
# rm -rf src/chrome/Debug
rv = [0]
def onError(func, path, excinfo):
Message("Couldn't remove '%s': %s" % (path, excinfo))
rv[0] = [1]
build_path = chrome_root + FixupPath("\\src\\chrome\\" + type)
Message("Cleaning: %s" % build_path)
shutil.rmtree(build_path, False, onError)
return rv[0]
def DoBuild(chrome_root, chrome_sln, clean, type):
"""devenv /build what we just checked out."""
if clean:
rv = DoClean(chrome_root, type)
if rv != 0:
Message("WARNING: Clean failed. Doing a build without clean.")
# devenv chrome.sln /build Debug
cmd = ["devenv.com", chrome_sln, "/build", type]
Message("Building: %s" % cmd)
sys.stdout.flush()
return subprocess.call(cmd, cwd=chrome_root)
def Main():
parser = optparse.OptionParser()
parser.add_option("", "--clean", action="store_true", default=False,
help="wipe Debug output directory before building")
parser.add_option("", "--solution", default="src\\chrome\\chrome.sln",
help="path to the .sln file to build (absolute, or "
"relative to chrome trunk")
parser.add_option("", "--release", action="store_true", default=False,
help="build the release configuration in addition of the "
"debug configuration.")
parser.add_option("", "--nosync", action="store_true", default=False,
help="doesn't sync before building")
parser.add_option("", "--print-latest", action="store_true", default=False,
help="print the latest buildable revision and exit")
options, args = parser.parse_args()
if options.print_latest:
print GetRevision() or "HEAD"
sys.exit(0)
if not args:
Message("Usage: %s <path\\to\\chrome\\root> [options]" % sys.argv[0])
sys.exit(1)
chrome_root = args[0]
if not options.nosync:
rv = DoUpdate(chrome_root)
if rv != 0:
Message("Update Failed. Bailing.")
sys.exit(rv)
chrome_sln = FixupPath(options.solution)
rv = DoBuild(chrome_root, chrome_sln, options.clean, "Debug")
if rv != 0:
Message("Debug build failed. Sad face :(")
if options.release:
rv = DoBuild(chrome_root, chrome_sln, options.clean, "Release")
if rv != 0:
Message("Release build failed. Sad face :(")
if rv != 0:
sys.exit(rv)
Message("Success!")
if __name__ == "__main__":
Main()
This source diff could not be displayed because it is too large. You can view the blob instead.
#!/bin/sh
base_dir=$(dirname "$0")
exec python "$base_dir/gcl.py" "$@"
@call python "%~dp0gcl.py" %*
This diff is collapsed.
#!/bin/sh
# Copyright (c) 2009 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
# This script will try to sync the bootstrap directories and then defer control.
base_dir=$(dirname "$0")
if [ "X$DEPOT_TOOLS_UPDATE" != "X0" -a -e "$base_dir/.svn" ]
then
# Update the bootstrap directory to stay up-to-date with the latest
# depot_tools.
svn -q up "$base_dir/bootstrap"
# Then defer the control to the bootstrapper.
"$base_dir/bootstrap/gclient.sh"
else
exec "$base_dir/gclient.py" "$@"
fi
@echo off
:: Copyright (c) 2009 The Chromium Authors. All rights reserved.
:: Use of this source code is governed by a BSD-style license that can be
:: found in the LICENSE file.
:: This file is a stub to sync .\bootstrap first and defer control to
:: .\bootstrap\gclient.bat, which will sync back '.'. This is unless auto
:: update is disabled, were gclient.py is directly called.
:: Shall skip automatic update?
IF "%DEPOT_TOOLS_UPDATE%" == "0" GOTO :SKIP_UPDATE
:: We can't sync if .\.svn\. doesn't exist.
IF NOT EXIST "%~dp0.svn" GOTO :SKIP_UPDATE
:: Will download svn and python if not already installed on the system.
call "%~dp0bootstrap\win\win_tools.bat"
if errorlevel 1 goto :EOF
:: Sync the bootstrap directory *only after*.
call svn up -q "%~dp0bootstrap"
:: still continue even in case of error.
goto :UPDATE
:SKIP_UPDATE
:: Don't bother to try to update any thing.
python "%~dp0\gclient.py" %*
goto :EOF
:UPDATE
:: Transfer control to ease the update process. The following lines won't be
:: executed so don't add any! Specifically, don't use 'call' in the following
:: line.
"%~dp0bootstrap\gclient.bat" %*
goto :EOF
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
#!/usr/bin/python
# Repo lives in ~evanm/projects/git-try -- feel free to send patches.
import getpass
import optparse
import os
import subprocess
import tempfile
import traceback
import urllib
import sys
def Backquote(cmd):
"""Like running `cmd` in a shell script."""
return subprocess.Popen(cmd, stdout=subprocess.PIPE).communicate()[0].strip()
def GetTryServerConfig():
"""Returns the dictionary of try server options or None if they
cannot be found."""
script_path = 'tools/tryserver/tryserver.py'
root_dir = Backquote(['git', 'rev-parse', '--show-cdup'])
try:
script_file = open(os.path.join(root_dir, script_path))
except IOError:
return None
locals = {}
try:
exec(script_file, locals)
except Exception, e:
return None
return locals
def GetBranchName():
"""Return name of current git branch."""
branch = Backquote(['git', 'symbolic-ref', 'HEAD'])
if not branch.startswith('refs/heads/'):
raise "Couldn't figure out branch name"
branch = branch[len('refs/heads/'):]
return branch
def GetPatchName():
"""Construct a name for this patch."""
# TODO: perhaps include the hash of the current commit, to distinguish
# patches?
return GetBranchName()
def GetRevision():
"""Get the latest Subversion revision number."""
for line in Backquote(['git', 'svn', 'info']).split('\n'):
if line.startswith('Revision:'):
return line[len('Revision:'):].strip()
raise "Couldn't figure out latest revision"
def GetRietveldIssueNumber():
return Backquote(['git', 'config',
'branch.%s.rietveldissue' % GetBranchName()])
def GetRietveldPatchsetNumber():
return Backquote(['git', 'config',
'branch.%s.rietveldpatchset' % GetBranchName()])
def GetMungedDiff(branch):
"""Get the diff we'll send to the try server. We munge paths to match svn."""
# Make the following changes:
# - Prepend "src/" to paths as svn is expecting
# - In the case of added files, replace /dev/null with the path to the file
# being added.
output = []
if not branch:
# Try to guess the upstream branch.
branch = Backquote(['git', 'cl', 'upstream'])
diff = subprocess.Popen(['git', 'diff-tree', '-p', '--no-prefix',
branch, 'HEAD'],
stdout=subprocess.PIPE).stdout.readlines()
for i in range(len(diff)):
line = diff[i]
if line.startswith('--- /dev/null'):
line = '--- %s' % diff[i+1][4:]
elif line.startswith('--- ') or line.startswith('+++ '):
line = line[0:4] + 'src/' + line[4:]
output.append(line)
return ''.join(output)
def GetEmail():
# TODO: check for errors here?
return Backquote(['git', 'config', 'user.email'])
def TryChange(args):
"""Put a patch on the try server using SVN."""
# TODO: figure out a better way to load trychange
script_path = '../depot_tools/release'
root_dir = Backquote(['git', 'rev-parse', '--show-cdup'])
sys.path.append(os.path.join(root_dir, script_path))
import trychange
trychange.checkout_root = os.path.abspath(root_dir)
trychange.TryChange(args, None, False)
def WriteTryDiffHTTP(config, patch_name, diff, options):
"""Put a patch on the try server."""
params = {
'user': getpass.getuser(),
'name': patch_name,
'patch': diff
}
if options.bot:
params['bot'] = options.bot
if options.clobber:
params['clobber'] = 'true'
url = 'http://%s:%s/send_try_patch' % (config['try_server_http_host'],
config['try_server_http_port'])
connection = urllib.urlopen(url, urllib.urlencode(params))
response = connection.read()
if (response != 'OK'):
print "Error posting to", url
print response
assert False
if __name__ == '__main__':
parser = optparse.OptionParser(
usage='git try [branch]',
description='Upload the current diff of branch...HEAD to the try server.')
parser.add_option("-b", "--bot",
help="Force the use of a specific build slave (eg mac, "
"win, or linux)")
parser.add_option("-c", "--clobber", action="store_true",
help="Make the try run use be a clobber build")
(options, args) = parser.parse_args(sys.argv)
branch = None
if len(args) > 1:
branch = args[1]
patch_name = GetPatchName()
diff = GetMungedDiff(branch)
# Send directly to try server if we can parse the config, otherwise
# upload via SVN.
config = GetTryServerConfig()
if config is not None:
print "Sending %s using HTTP..." % patch_name
WriteTryDiffHTTP(config=config, patch_name=patch_name, diff=diff,
options=options)
else:
print "Sending %s using SVN..." % patch_name
# Write the diff out to a temporary file
diff_file = tempfile.NamedTemporaryFile()
diff_file.write(diff)
diff_file.flush()
email = GetEmail()
user = email.partition('@')[0]
args = [
'--use_svn',
'--svn_repo', 'svn://svn.chromium.org/chrome-try/try',
'-u', user,
'-e', email,
'-n', patch_name,
'-r', GetRevision(),
'--diff', diff_file.name,
]
if GetRietveldPatchsetNumber():
args.extend([
'--issue', GetRietveldIssueNumber(),
'--patchset', GetRietveldPatchsetNumber(),
])
TryChange(args=args)
#!/bin/sh
# The first expression catches when we're actually in the /src directory.
# The second expressions strips everything after the last /src occurrence.
SRC_DIR=`pwd | sed -e '\;/src$;q' -e 's;\(.*/src\)/.*;\1;'`
SCONS="${SRC_DIR}/third_party/scons/scons.py"
SITE_SCONS="${SRC_DIR}/site_scons"
exec python "${SCONS}" "--site-dir=${SITE_SCONS}" "$@"
@echo off
@rem We're in a submodule directory, look relative to the parent.
call python "%cd%\..\third_party\scons\scons.py" "--site-dir=..\site_scons" %*
goto omega
:srcdir
call python "%cd%\third_party\scons\scons.py" --site-dir=site_scons %*
goto omega
@rem Per the following page:
@rem http://code-bear.com/bearlog/2007/06/01/getting-the-exit-code-from-a-batch-file-that-is-run-from-a-python-program/
@rem Just calling "exit /b" passes back an exit code, but in a way
@rem that does NOT get picked up correctly when executing the .bat
@rem file from the Python subprocess module. Using "call" as the
@rem last command in the .bat file makes it work as expected.
:returncode
exit /b %ERRORLEVEL%
:omega
call :returncode %ERRORLEVEL%
This diff is collapsed.
#!/usr/bin/env python
# Copyright (c) 2006-2009 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Generic presubmit checks that can be reused by other presubmit checks."""
def CheckChangeHasTestedField(input_api, output_api):
"""Requires that the changelist have a TESTED= field."""
if input_api.change.Tested:
return []
else:
return [output_api.PresubmitError("Changelist must have a TESTED= field.")]
def CheckChangeHasQaField(input_api, output_api):
"""Requires that the changelist have a QA= field."""
if input_api.change.QA:
return []
else:
return [output_api.PresubmitError("Changelist must have a QA= field.")]
def CheckDoNotSubmitInDescription(input_api, output_api):
"""Checks that the user didn't add 'DO NOT ' + 'SUBMIT' to the CL description.
"""
keyword = 'DO NOT ' + 'SUBMIT'
if keyword in input_api.change.DescriptionText():
return [output_api.PresubmitError(
keyword + " is present in the changelist description.")]
else:
return []
def CheckDoNotSubmitInFiles(input_api, output_api):
"""Checks that the user didn't add 'DO NOT ' + 'SUBMIT' to any files."""
keyword = 'DO NOT ' + 'SUBMIT'
for f, line_num, line in input_api.RightHandSideLines():
if keyword in line:
text = 'Found ' + keyword + ' in %s, line %s' % (f.LocalPath(), line_num)
return [output_api.PresubmitError(text)]
return []
def CheckDoNotSubmit(input_api, output_api):
return (
CheckDoNotSubmitInDescription(input_api, output_api) +
CheckDoNotSubmitInFiles(input_api, output_api)
)
def CheckChangeHasNoTabs(input_api, output_api):
"""Checks that there are no tab characters in any of the text files to be
submitted.
"""
for f, line_num, line in input_api.RightHandSideLines():
if '\t' in line:
return [output_api.PresubmitError(
"Found a tab character in %s, line %s" %
(f.LocalPath(), line_num))]
return []
def CheckLongLines(input_api, output_api, maxlen=80):
"""Checks that there aren't any lines longer than maxlen characters in any of
the text files to be submitted.
"""
basename = input_api.basename
bad = []
for f, line_num, line in input_api.RightHandSideLines():
if line.endswith('\n'):
line = line[:-1]
if len(line) > maxlen:
bad.append(
'%s, line %s, %s chars' %
(basename(f.LocalPath()), line_num, len(line)))
if len(bad) == 5: # Just show the first 5 errors.
break
if bad:
msg = "Found lines longer than %s characters (first 5 shown)." % maxlen
return [output_api.PresubmitPromptWarning(msg, items=bad)]
else:
return []
def CheckTreeIsOpen(input_api, output_api, url, closed):
"""Checks that an url's content doesn't match a regexp that would mean that
the tree is closed."""
try:
connection = input_api.urllib2.urlopen(url)
status = connection.read()
connection.close()
if input_api.re.match(closed, status):
long_text = status + '\n' + url
return [output_api.PresubmitError("The tree is closed.",
long_text=long_text)]
except IOError:
pass
return []
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<Profile FormatVersion="1">
<Tools>
<Tool Filename="python" AllowIntercept="true" />
<Tool Filename="cl" AllowRemote="true" VCCompiler="true" />
<Tool Filename="link" AllowRemote="false" />
</Tools>
</Profile>
#!/bin/sh
base_dir=$(dirname "$0")
exec python "$base_dir/revert.py" "$@"
@python "%~dp0revert.py" %*
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment