
Change-Id: I4134461984fff33f9e6470cb7b4982ba51802dab Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2505581 Reviewed-by: Caleb Raitto <caraitto@chromium.org> Reviewed-by: Mark Cogan <marq@chromium.org> Commit-Queue: Caleb Raitto <caraitto@chromium.org> Cr-Commit-Position: refs/heads/master@{#822167}
224 lines
9.8 KiB
Markdown
224 lines
9.8 KiB
Markdown
# Working With Files
|
|
|
|
Adding, removing, and renaming files in iOS Chromium needs to follow a specific
|
|
procedure that will be unfamiliar to engineers coming from other iOS projects.
|
|
Conceptually, every file is recorded in _four_ locations: the local filesystem,
|
|
git, the `BUILD.gn` files, and the XCode projects. Of these, the XCode project
|
|
is wholly generated from the others.
|
|
|
|
[TOC]
|
|
|
|
## Overview
|
|
|
|
**Do not use XCode to manipulate files.** The XCode project used for iOS
|
|
Chromium is _generated_; it's functionally a build artifact. The various
|
|
`BUILD.gn` files in Chromium define structure of the XCode project file. Running
|
|
`gclient runhooks` causes the project files to be regenerated.
|
|
|
|
Individual files can have their contents edited within XCode, and all of the
|
|
regular testing and debugging activities can be done within XCode. It just can't
|
|
be used to create files, rename files, delete files, or manipulate the project
|
|
group structure in any way. To do these things, follow the procedures below.
|
|
|
|
## Adding files
|
|
|
|
To add any files (new headers, `.mm` or `.cc` implementation files, asset files
|
|
of any kind), the following general steps need to happen:
|
|
|
|
1. The file needs to exist in the correct directory of the file system for your
|
|
Chromium checkout. New files need to be created, or assets need to be
|
|
copied to the right location.
|
|
|
|
1. The new files need to be added to git.
|
|
|
|
1. The new files need to be added to a target in a `BUILD.gn` file (usually in
|
|
the same directory as the newly added file).
|
|
|
|
1. The XCode project needs to be regenerated.
|
|
|
|
For adding new header or implementation files, the following procedure is
|
|
recommended:
|
|
|
|
1. Generate the new files using `tools/boilerplate.py`. This will generate the
|
|
correct header guard macros and include the copyright boilerplate.
|
|
|
|
2. Add the newly created files using `git add`.
|
|
|
|
3. Edit the `BUILD.gn` file for the directory where the files were added. For
|
|
each file, add it to the `sources` list for the correct `source_set` in the
|
|
`BUILD.gn` file. Note that `gn format` (which is run as part of `git cl
|
|
format`) will take care of alphabetizing the lists along with other
|
|
formatting, so there's no need to manually do these things. (`BUILD.gn`
|
|
files cand be edited directly in XCode, or in another editor such as `vi`).
|
|
|
|
4. Once all of the files have been created, `add`ed and all `BUILD.gn` files
|
|
have been updated, run `gclient runhooks` to regenerate all XCode projects.
|
|
|
|
5. If XCode is open, it may prompt to "Autocreate Schemes". If so, click on the
|
|
highlighted "Automatically Create Schemes" button.
|
|
|
|
In the shell, this procedure would look like this:
|
|
```bash
|
|
// Step 1 -- generate new files.
|
|
$ tools/boilerplate.py ios/chrome/browser/some_feature/feature_class.h
|
|
$ tools/boilerplate.py ios/chrome/browser/some_feature/feature_class.mm
|
|
$ tools/boilerplate.py ios/chrome/browser/some_feature/feature_class_unittest.mm
|
|
// Step 2 -- add the new files.
|
|
$ git add ios/chrome/browser/some_feature/feature_class*
|
|
// Step 3 -- edit the BUILD.gn file in the editor of your choice
|
|
$ vi ios/chrome/browser/some_feature/BUILD.gn
|
|
// Step 4 -- regenerate the XCode Projects
|
|
$ gclient runhooks
|
|
```
|
|
|
|
To add asset files, follow this procedure:
|
|
|
|
1. Copy the asset files to the correct directory, with the correct names
|
|
(including `@2x` and `@3x` suffixes) Note that images are stored in
|
|
`.imageset` directories, conventionally inside `resources` directories for a
|
|
given UI feature. New directories, if needed, are created in the usual way
|
|
(`mkdir`). Note that there is no equivalent of `boilerplate.py` for images
|
|
or other asset files.
|
|
|
|
1. Create or copy `Contents.json` files for each new `.imageset` directory,
|
|
with the appropriate contents.
|
|
|
|
1. Add all image and `Contents.json` files using `git add`.
|
|
|
|
1. Edit the `BUILD.gn` file in the containing `resources` directory, adding
|
|
`imageset` entries for each added `.imageset` directory, and then grouping
|
|
all assets into a new or existing `group()` declaration with a `public_deps`
|
|
list containing all of the `imageset` targets.
|
|
|
|
1. Regenerate the XCode project with `gclient runhooks`.
|
|
|
|
To add Markdown documentation files, the procedure is much simpler. These files
|
|
are automatically added to the XCode project without `BUILD.gn` entries, and
|
|
they have no required boilerplate. So adding new docs is as simple as:
|
|
|
|
1. Create a new `.md` file in the appropriate directory (`docs/ios`, for
|
|
example).
|
|
|
|
1. `git add` the file.
|
|
|
|
The newly added file will be visible in XCode after the next `gclient runhooks`.
|
|
|
|
## Moving and renaming files.
|
|
|
|
Renaming a file involves updating the filename in all of the places where it
|
|
exists: the file names in the filesystem, the file names in git, header guards
|
|
in files, import declarations in files, listings in BUILD.gn files, and
|
|
internally in the XCode project. As with adding a file, different tools are used
|
|
for each of these. Unlike creating a file, which starts with actually adding a
|
|
file to the filesystem, a rename starts with updating git (via `git mv`), then
|
|
using the `mass-rename` tool to update file contents.
|
|
|
|
`tools/git/mass-rename.py` works by looking at _uncommitted_ file moves in git,
|
|
and then updating all includes, header guards, and BUILD.gn entries to use the
|
|
new name. It doesn't update some other files, such as `Contents.json` files for
|
|
image assets. It also doesn't change any symbols in code, so class and variable
|
|
names won't be changed.
|
|
|
|
For many file moves, it will be simpler to use another tool,
|
|
`tools/git/move_source_file.py`, which combines `git mv` and `mass-rename` in a
|
|
single action. For example, renaming `feature_class` to `renamed_class` would be
|
|
done like this:
|
|
```bash
|
|
$ tools/git/move_source_file.py ios/chrome/browser/some_feature/feature_class.h \
|
|
ios/chrome/browser/some_feature/renamed_class.h
|
|
$ tools/git/move_source_file.py ios/chrome/browser/some_feature/feature_class.mm \
|
|
ios/chrome/browser/some_feature/renamed_class.mm
|
|
```
|
|
|
|
The step-by-step procedure for a rename is:
|
|
|
|
1. If there are other uncommitted changes before the move, it's usually
|
|
cleanest to commit before starting the move.
|
|
|
|
1. `move_source_file` each file that needs to be renamed. This renames the file
|
|
in both the file system and in git, and in most places where it's used in
|
|
code.
|
|
|
|
1. Run `gclient runhooks` to update the XCode project. Check that all of the
|
|
needed name changes have been made (for example, by building all targets).
|
|
Make any other needed fixes.
|
|
|
|
1. If any classes or other symbols need to be renamed (remember that the name
|
|
of the primary interface in each file must match the file name), make those
|
|
changes. Find-and-replace tools like `tools/git/mffr.py` or XCode's
|
|
Find/Replace can help here, but there are no compiler-aware tools that can
|
|
do a "smart" rename.
|
|
|
|
1. Commit all changes (`git commit -a -m <your comment>`).
|
|
|
|
A move—where a file is moved to a different directory—is in most respects
|
|
performed using the same steps as a rename. However, while `mass-rename.py` (and
|
|
thus `move_source_file.py`) will update existing file names in `BUILD.gn` files,
|
|
it won't move entries from one `BUILD.gn` file to another. To move files to a
|
|
different directory, the preceding procedure is used, but between steps 2 and 3
|
|
(after moving the files, but before regenerating the XCode project), the old
|
|
filenames will need to be removed from the `BUILD.gn` files in the old
|
|
directories and added to the `BUILD.gn` files in the new directories.
|
|
|
|
Also note that while `move_source_file` must be used separately for each file
|
|
being renamed within a directory, it (just like `git mv`) can move multiple
|
|
files without renaming to a new directory in a single command:
|
|
|
|
```bash
|
|
$ tools/git/mass-rename.py ios/chrome/browser/some_feature/feature_class.* \
|
|
ios/chrome/browser/some_feature/feature_class_unittest.mm \
|
|
ios/chrome/browser/other_feature/
|
|
```
|
|
|
|
## Deleting files.
|
|
|
|
Deleting files follows the same patterns as adding and moving files. As with a
|
|
file move, it's best to begin with deleting the files from git.
|
|
|
|
Typically, before actually removing a file, first all usage of the interface(s)
|
|
in the file(s) will be removed, and the file will no longer be `#imported`
|
|
anywhere.
|
|
|
|
Step-by step:
|
|
|
|
1. `git rm` the files you want to remove. This will also remove the files
|
|
from the filesystem.
|
|
|
|
1. Manually remove the `BUILD.gn` entries for the files.
|
|
|
|
1. Regenerate the XCode project (with `gclient runhooks`) to remove the files
|
|
from XCode.
|
|
|
|
## Finally.
|
|
|
|
It's easy to miss some uses of a file that was renamed or deleted, and fixing
|
|
compilation errors discovered in the commit queue means another
|
|
commit-upload-dry run cycle (at least). To minimize this, after any change that
|
|
adds, renames, moves, or deletes files, be sure to take the following steps:
|
|
|
|
1. `git cl format` to update the formatting of all files.
|
|
|
|
1. `gn check` to make sure that any new or moved files follow the dependency
|
|
rules (for example: `gn check -C out/Debug-iphonesimulator/`).
|
|
|
|
1. Build all targets, to make sure that everything has been added, changed, or
|
|
removed correctly. This can be done by selecting the "All" target in XCode
|
|
and building (`⌘-B`), or from the command line (for example, `autoninja -C
|
|
out/Debug-iphonesimulator/`).
|
|
|
|
Changes that involve adding or deleting more than a few files, and most renames
|
|
of any size, should be in a single CL with no other changes, for ease of
|
|
reviewing and (if necessary) reverting or cherry-picking.
|
|
|
|
## Recovering from accidental XCode Project usage.
|
|
|
|
If files are accidentally added, renamed, or moved through XCode, other settings
|
|
in the XCode project may be changed that will introduce strange local build
|
|
failures. In this case, take the following steps to recover.
|
|
|
|
1. Quit XCode.
|
|
|
|
1. Delete all generated XCode projects and associated files: `rm -rf out/build`.
|
|
|
|
1. Regenerate all XCode projects: `gclient runhooks`.
|