Name Date Size #Lines LOC

..--

docs/H25-Apr-2025-4530

tests/H25-Apr-2025-1,230838

.gitignoreH A D25-Apr-202543 65

Android.bpH A D25-Apr-20254.8 KiB186171

MakefileH A D25-Apr-2025457 2113

OWNERSH A D25-Apr-202540 32

README.mdH A D25-Apr-20255.8 KiB185131

archive_utils.pyH A D25-Apr-20253.5 KiB13484

base_updater.pyH A D25-Apr-20254.6 KiB13190

color.pyH A D25-Apr-20251 KiB3815

conftest.pyH A D25-Apr-20251 KiB3312

crates_updater.pyH A D25-Apr-20259.3 KiB221163

external_updater.pyH A D25-Apr-202516.2 KiB442325

external_updater_reviewers_test.pyH A D25-Apr-20255.9 KiB13796

fileutils.pyH A D25-Apr-20258.9 KiB240168

git_updater.pyH A D25-Apr-20255.7 KiB13292

git_utils.pyH A D25-Apr-202510.6 KiB304213

github_archive_updater.pyH A D25-Apr-20257.2 KiB197141

hashtags.pyH A D25-Apr-2025901 237

manifest.pyH A D25-Apr-20253.8 KiB11678

metadata.protoH A D25-Apr-20252.5 KiB10790

notifier.pyH A D25-Apr-20256.5 KiB227162

poetry.lockH A D25-Apr-202511.4 KiB247220

pyproject.tomlH A D25-Apr-2025610 2924

regen_bp.shH A D25-Apr-20255.3 KiB164111

reviewers.pyH A D25-Apr-20255 KiB12565

test_base_updater.pyH A D25-Apr-20251.9 KiB5725

test_fileutils.pyH A D25-Apr-20254.3 KiB12485

test_github_archive_updater.pyH A D25-Apr-20251.9 KiB4926

test_manifest.pyH A D25-Apr-20259.9 KiB274225

test_updater_utils.pyH A D25-Apr-20253.6 KiB8451

update_package.shH A D25-Apr-20253 KiB11074

updater.shH A D25-Apr-20251,009 265

updater_utils.pyH A D25-Apr-20255.1 KiB153106

README.md

1# external_updater
2
3external updater is a tool to automatically update libraries in external/.
4
5The documentation on this page is for users of `external_updater`. If you're
6looking for developer docs, see [docs/dev.md](docs/dev.md).
7
8## Usage
9
10In each of the examples below, `$PROJECT_PATH` is the path to the project to
11operate on. If more than one path is given, external_updater will operate on
12each in turn.
13
14Note: Older versions of external_updater used a different path resolution
15method. Relative paths were resolved relative to `//external` rather than the
16CWD, which meant tab-completed paths would only work if the CWD was
17`//external`, and that wildcards had to be escaped for processing by
18external_updater rather than the shell (e.g.
19`updater.sh 'check rust/crates/*'`). That behavior was removed to support CWD
20relative paths. If you want the old behavior back, leave a comment on
21http://b/243685332 or https://r.android.com/2855445.
22
23Check updates for a library or verify METADATA is valid:
24
25```shell
26tools/external_updater/updater.sh check $PROJECT_PATH
27```
28
29Update a library, commit, and upload the change to Gerrit:
30
31```shell
32tools/external_updater/updater.sh update $PROJECT_PATH
33```
34
35Update a library without committing and uploading to Gerrit:
36
37```shell
38tools/external_updater/updater.sh update --no-upload $PROJECT_PATH
39```
40
41Update a library to a specific version:
42
43```shell
44tools/external_updater/updater.sh update --custom-version $VERSION $PROJECT_PATH
45```
46
47Update a library on top of the local changes in the current branch, commit, and upload the change to Gerrit:
48
49```shell
50tools/external_updater/updater.sh update --keep-local-changes $PROJECT_PATH
51```
52
53Update a library without building:
54
55```shell
56tools/external_updater/updater.sh update --no-build $PROJECT_PATH
57```
58
59Update a library and add bug number to the commit message:
60
61```shell
62tools/external_updater/updater.sh update --bug $BUG_NUMBER $PROJECT_PATH
63```
64
65PROJECT_PATH can be the path to a library under external/, e.g.
66external/kotlinc, or external/python/cpython3.
67
68## Configure
69
70To use this tool, a METADATA file must present at the root of the
71repository. The full definition can be found in
72[metadata.proto](https://android.googlesource.com/platform/tools/external_updater/+/refs/heads/main/metadata.proto).
73Or
74[external/toybox/METADATA](https://android.googlesource.com/platform/external/toybox/+/refs/heads/main/METADATA)
75is a concrete example.
76
77The most important part in the file is a list of urls.
78`external_updater` will go through all urls and uses the first
79supported url.
80
81### Git upstream
82
83If type of a URL is set to GIT, the URL must be a git upstream
84(the one you can use with `git clone`). And the version field must
85be either a version tag, or SHA. The tool will find the latest
86version tag or sha based on it.
87
88When upgrade, the tool will simply run `git merge tag/sha`.
89
90IMPORTANT: It is suggested to set up a `upstream-main` branch to
91replicate upstream. Because most users don't have the privilege to
92upload changes not authored by themselves. This can be done by
93filing a bug to componentid:99104.
94
95#### SHA
96
97If the version is a SHA, the tool will always try to upgrade to the
98top of upstream. As long as there is any new change upstream, local
99library will be treated as stale.
100
101#### Version tag
102
103If the version is not a SHA, the tool will try to parse the version
104to get a numbered version. Currently the supported version format is:
105
106```markdown
107<prefix><version_number><suffix>
108```
109
110version_number part can be numbers separated by `.` or `-` or `_`.
111
112If you have project where this isn't working, file a bug so we can take a look.
113
114#### Local changes
115
116It is suggested to verify all local changes when upgrading. This can
117be done easily in Gerrit, by comparing parent2 and the patchset.
118
119
120### GitHub archive
121
122If the url type is ARCHIVE, and the url is from GitHub, `external_updater`
123can upgrade a library based on GitHub releases.
124
125If you have the choice between archives and git tags, choose tags.
126Because that makes it easier to manage local changes.
127
128The tool will query GitHub to get the latest release from:
129
130```url
131https://github.com/user/proj/releases/latest
132```
133
134If the tag of latest release is not equal to version in METADATA file, a
135new version is found. The tool will download the tarball and overwrite the
136library with it.
137
138If there are multiple archives in one GitHub release, the one most
139[similar](https://en.wikipedia.org/wiki/Edit_distance) to previous
140(from METADATA) will be used.
141
142After upgrade, files not present in the new tarball will be removed. But we
143explicitly keep files famous in Android tree.
144See [update_package.sh](https://android.googlesource.com/platform/tools/external_updater/+/refs/heads/main/update_package.sh).
145
146If more files need to be reserved, a post_update.sh can be created to copy
147these files over.
148See [example](https://android.googlesource.com/platform/external/kotlinc/+/refs/heads/main/post_update.sh).
149
150#### Local patches
151
152Local patches can be kept as patches/*.diff. They will be applied after
153upgrade. [example](https://cs.android.com/android/platform/superproject/main/+/main:external/jsmn/patches/header.diff)
154
155## Email notification
156
157There is some support to automatically check updates for all external
158libraries every hour, send email and change. Currently this is done by
159running the following script on a desktop machine.
160
161```shell
162#!/bin/bash
163
164cd /src/aosp
165while true
166do
167        repo abandon tmp_auto_upgrade
168        repo forall -c git checkout .
169        repo forall -c git clean -xdf
170        repo sync -c
171        source build/envsetup.sh
172        lunch aosp_arm-eng
173        mmma tools/external_updater
174
175        out/soong/host/linux-x86/bin/external_updater_notifier \
176                --history ~/updater/history \
177                [email protected] \
178                --generate_change \
179                --all
180        date
181        echo "Sleeping..."
182        sleep 3600
183done
184```
185