Home | History | Annotate | only in /tools/repohooks
Up to higher level directory
NameDateSize
.gitignore05-Oct-20176
OWNERS05-Oct-201718
pre-upload.py05-Oct-201713.1K
PREUPLOAD.cfg05-Oct-2017293
README.md05-Oct-20179K
rh/05-Oct-2017
tools/05-Oct-2017

README.md

      1 # AOSP Presubmit Hooks
      2 
      3 [TOC]
      4 
      5 This repo holds hooks that get run by repo during the upload phase.  They
      6 perform various checks automatically such as running linters on your code.
      7 
      8 Note: Currently all hooks are disabled by default.  Each repo must explicitly
      9 turn on any hook it wishes to enforce.
     10 
     11 ## Usage
     12 
     13 Normally these execute automatically when you run `repo upload`.  If you want to
     14 run them by hand, you can execute `pre-upload.py` directly.  By default, that
     15 will scan the active repo and process all commits that haven't yet been merged.
     16 See its help for more info.
     17 
     18 ### Bypassing
     19 
     20 Sometimes you might want to bypass the upload checks.  While this is **strongly
     21 discouraged** (often failures you add will affect others and block them too),
     22 sometimes there are valid reasons for this.  You can simply use the option
     23 `--no-verify` when running `repo upload` to skip all upload checks.  This will
     24 skip **all** checks and not just specific ones.  It should be used only after
     25 having run & evaluated the upload output previously.
     26 
     27 # Config Files
     28 
     29 There are two types of config files:
     30 * Repo project-wide settings (e.g. all of AOSP).  These set up defaults for all
     31   projects that are checked out via a single manifest.
     32 * Project-local settings (e.g. a single .git repo).  These control settings for
     33   the local project you're working on.
     34 
     35 The merging of these config files control the hooks/checks that get run when
     36 running `repo upload`.
     37 
     38 ## GLOBAL-PREUPLOAD.cfg
     39 
     40 These are the manifest-wide defaults and can be located in two places:
     41 * `.repo/manifests/GLOBAL-PREUPLOAD.cfg`: The manifest git repo.
     42   Simply check this in to the manifest git repo and you're done.
     43 * `GLOBAL-PREUPLOAD.cfg`: The top level of the repo checkout.
     44   For manifests that don't have a project checked out at the top level,
     45   you can use repo's `<copyfile>` directive.
     46 
     47 These config files will be loaded first before stacking `PREUPLOAD.cfg`
     48 settings on top.
     49 
     50 ## PREUPLOAD.cfg
     51 
     52 This file are checked in the top of a specific git repository.  Stacking them
     53 in subdirectories (to try and override parent settings) is not supported.
     54 
     55 ## Example
     56 
     57 ```
     58 [Options]
     59 ignore_merged_commits = true
     60 
     61 [Hook Scripts]
     62 name = script --with args ${PREUPLOAD_FILES}
     63 
     64 [Builtin Hooks]
     65 cpplint = true
     66 
     67 [Builtin Hooks Options]
     68 cpplint = --filter=-x ${PREUPLOAD_FILES}
     69 
     70 [Tool Paths]
     71 clang-format = /usr/bin/clang-format
     72 ```
     73 
     74 ## Environment
     75 
     76 Hooks are executed in the top directory of the git repository.  All paths should
     77 generally be relative to that point.
     78 
     79 A few environment variables are set so scripts don't need to discover things.
     80 
     81 * `REPO_PROJECT`: The name of the project.
     82    e.g. `platform/tools/repohooks`
     83 * `REPO_PATH`: The path to the project relative to the root.
     84    e.g. `tools/repohooks`
     85 * `REPO_REMOTE`: The name of the git remote.
     86    e.g. `aosp`.
     87 * `REPO_LREV`: The name of the remote revision, translated to a local tracking
     88    branch. This is typically latest commit in the remote-tracking branch.
     89    e.g. `ec044d3e9b608ce275f02092f86810a3ba13834e`
     90 * `REPO_RREV`: The remote revision.
     91    e.g. `master`
     92 * `PREUPLOAD_COMMIT`: The commit that is currently being checked.
     93    e.g. `1f89dce0468448fa36f632d2fc52175cd6940a91`
     94 
     95 ## Placeholders
     96 
     97 A few keywords are recognized to pass down settings.  These are **not**
     98 environment variables, but are expanded inline.  Files with whitespace and
     99 such will be expanded correctly via argument positions, so do not try to
    100 force your own quote handling.
    101 
    102 * `${PREUPLOAD_FILES}`: List of files to operate on.
    103 * `${PREUPLOAD_COMMIT}`: Commit hash.
    104 * `${PREUPLOAD_COMMIT_MESSAGE}`: Commit message.
    105 
    106 Some variables are available to make it easier to handle OS differences.  These
    107 are automatically expanded for you:
    108 
    109 * `${REPO_ROOT}`: The absolute path of the root of the repo checkout.
    110 * `${BUILD_OS}`: The string `darwin-x86` for macOS and the string `linux-x86`
    111   for Linux/x86.
    112 
    113 ## [Options]
    114 
    115 This section allows for setting options that affect the overall behavior of the
    116 pre-upload checks.  The following options are recognized:
    117 
    118 * `ignore_merged_commits`: If set to `true`, the hooks will not run on commits
    119   that are merged.  Hooks will still run on the merge commit itself.
    120 
    121 ## [Hook Scripts]
    122 
    123 This section allows for completely arbitrary hooks to run on a per-repo basis.
    124 
    125 The key can be any name (as long as the syntax is valid), as can the program
    126 that is executed. The key is used as the name of the hook for reporting purposes,
    127 so it should be at least somewhat descriptive.
    128 
    129 ```
    130 [Hook Scripts]
    131 my_first_hook = program --gogog ${PREUPLOAD_FILES}
    132 another_hook = funtimes --i-need "some space" ${PREUPLOAD_FILES}
    133 some_fish = linter --ate-a-cat ${PREUPLOAD_FILES}
    134 some_cat = formatter --cat-commit ${PREUPLOAD_COMMIT}
    135 some_dog = tool --no-cat-in-commit-message ${PREUPLOAD_COMMIT_MESSAGE}
    136 ```
    137 
    138 ## [Builtin Hooks]
    139 
    140 This section allows for turning on common/builtin hooks.  There are a bunch of
    141 canned hooks already included geared towards AOSP style guidelines.
    142 
    143 * `checkpatch`: Run commits through the Linux kernel's `checkpatch.pl` script.
    144 * `clang_format`: Run git-clang-format against the commit. The default style is
    145   `file`.
    146 * `commit_msg_bug_field`: Require a valid `Bug:` line.
    147 * `commit_msg_changeid_field`: Require a valid `Change-Id:` Gerrit line.
    148 * `commit_msg_test_field`: Require a `Test:` line.
    149 * `cpplint`: Run through the cpplint tool (for C++ code).
    150 * `gofmt`: Run Go code through `gofmt`.
    151 * `google_java_format`: Run Java code through
    152   [`google-java-format`](https://github.com/google/google-java-format)
    153 * `jsonlint`: Verify JSON code is sane.
    154 * `pylint`: Run Python code through `pylint`.
    155 * `xmllint`: Run XML code through `xmllint`.
    156 
    157 Note: Builtin hooks tend to match specific filenames (e.g. `.json`).  If no
    158 files match in a specific commit, then the hook will be skipped for that commit.
    159 
    160 ```
    161 [Builtin Hooks]
    162 # Turn on cpplint checking.
    163 cpplint = true
    164 # Turn off gofmt checking.
    165 gofmt = false
    166 ```
    167 
    168 ## [Builtin Hooks Options]
    169 
    170 Used to customize the behavior of specific `[Builtin Hooks]`.  Any arguments set
    171 here will be passed directly to the linter in question.  This will completely
    172 override any existing default options, so be sure to include everything you need
    173 (especially `${PREUPLOAD_FILES}` -- see below).
    174 
    175 Quoting is handled naturally.  i.e. use `"a b c"` to pass an argument with
    176 whitespace.
    177 
    178 See [Placeholders](#Placeholders) for variables you can expand automatically.
    179 
    180 ```
    181 [Builtin Hooks Options]
    182 # Pass more filter args to cpplint.
    183 cpplint = --filter=-x ${PREUPLOAD_FILES}
    184 ```
    185 
    186 ## [Tool Paths]
    187 
    188 Some builtin hooks need to call external executables to work correctly.  By
    189 default it will call those tools from the user's `$PATH`, but the paths of those
    190 executables can be overridden through `[Tool Paths]`.  This is helpful to
    191 provide consistent behavior for developers across different OS and Linux
    192 distros/versions.  The following tools are recognized:
    193 
    194 * `clang-format`: used for the `clang_format` builtin hook.
    195 * `cpplint`: used for the `cpplint` builtin hook.
    196 * `git-clang-format`: used for the `clang_format` builtin hook.
    197 * `gofmt`: used for the `gofmt` builtin hook.
    198 * `google-java-format`: used for the `google_java_format` builtin hook.
    199 * `google-java-format-diff`: used for the `google_java_format` builtin hook.
    200 * `pylint`: used for the `pylint` builtin hook.
    201 
    202 See [Placeholders](#Placeholders) for variables you can expand automatically.
    203 
    204 ```
    205 [Tool Paths]
    206 # Pass absolute paths.
    207 clang-format = /usr/bin/clang-format
    208 # Or paths relative to the top of the git project.
    209 clang-format = prebuilts/bin/clang-format
    210 # Or paths relative to the repo root.
    211 clang-format = ${REPO_ROOT}/prebuilts/clang/host/${BUILD_OS}/clang-stable/bin/clang-format
    212 ```
    213 
    214 # Hook Developers
    215 
    216 These are notes for people updating the `pre-upload.py` hook itself:
    217 
    218 * Don't worry about namespace collisions.  The `pre-upload.py` script is loaded
    219   and exec-ed in its own context.  The only entry-point that matters is `main`.
    220 * New hooks can be added in `rh/hooks.py`.  Be sure to keep the list up-to-date
    221   with the documentation in this file.
    222 
    223 ## TODO/Limitations
    224 
    225 * `pylint` should support per-repo pylintrc files.
    226 * Some checkers operate on the files as they exist in the filesystem.  This is
    227   not easy to fix because the linters require not just the modified file but the
    228   entire repo in order to perform full checks.  e.g. `pylint` needs to know what
    229   other modules exist locally to verify their API.  We can support this case by
    230   doing a full checkout of the repo in a temp dir, but this can slow things down
    231   a lot.  Will need to consider a `PREUPLOAD.cfg` knob.
    232 * We need to add `pylint` tool to the AOSP manifest and use that local copy
    233   instead of relying on the version that is in $PATH.
    234 * Should make file extension filters configurable.  All hooks currently declare
    235   their own list of files like `.cc` and `.py` and `.xml`.
    236 * Add more checkers.
    237   * `clang-check`: Runs static analyzers against code.
    238   * License checking (like require AOSP header).
    239   * Whitespace checking (trailing/tab mixing/etc...).
    240   * Long line checking.
    241   * Commit message checks (correct format/BUG/TEST/SOB tags/etc...).
    242   * Markdown (gitiles) validator.
    243   * Spell checker.
    244