Skip to content

Commit d4b6e90

Browse files
committed
Migrate package include/exclude to gitignore patterns.
1 parent 29b000f commit d4b6e90

File tree

3 files changed

+209
-61
lines changed

3 files changed

+209
-61
lines changed

src/cargo/sources/path.rs

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -101,10 +101,10 @@ impl<'cfg> PathSource<'cfg> {
101101
/// stages are:
102102
///
103103
/// 1) Only warn users about the future change iff their matching rules are
104-
/// affected. (CURRENT STAGE)
104+
/// affected.
105105
///
106106
/// 2) Switch to the new strategy and update documents. Still keep warning
107-
/// affected users.
107+
/// affected users. (CURRENT STAGE)
108108
///
109109
/// 3) Drop the old strategy and no more warnings.
110110
///
@@ -122,22 +122,26 @@ impl<'cfg> PathSource<'cfg> {
122122
p
123123
};
124124
Pattern::new(pattern)
125-
.map_err(|e| failure::format_err!("could not parse glob pattern `{}`: {}", p, e))
126125
};
127126

128127
let glob_exclude = pkg
129128
.manifest()
130129
.exclude()
131130
.iter()
132131
.map(|p| glob_parse(p))
133-
.collect::<Result<Vec<_>, _>>()?;
132+
.collect::<Result<Vec<_>, _>>();
134133

135134
let glob_include = pkg
136135
.manifest()
137136
.include()
138137
.iter()
139138
.map(|p| glob_parse(p))
140-
.collect::<Result<Vec<_>, _>>()?;
139+
.collect::<Result<Vec<_>, _>>();
140+
141+
// Don't warn about glob mismatch if it doesn't parse.
142+
let glob_is_valid = glob_exclude.is_ok() && glob_include.is_ok();
143+
let glob_exclude = glob_exclude.unwrap_or_else(|_| Vec::new());
144+
let glob_include = glob_include.unwrap_or_else(|_| Vec::new());
141145

142146
let glob_should_package = |relative_path: &Path| -> bool {
143147
fn glob_match(patterns: &[Pattern], relative_path: &Path) -> bool {
@@ -210,46 +214,45 @@ impl<'cfg> PathSource<'cfg> {
210214
let glob_should_package = glob_should_package(relative_path);
211215
let ignore_should_package = ignore_should_package(relative_path)?;
212216

213-
if glob_should_package != ignore_should_package {
217+
if glob_is_valid && glob_should_package != ignore_should_package {
214218
if glob_should_package {
215219
if no_include_option {
216220
self.config.shell().warn(format!(
217-
"Pattern matching for Cargo's include/exclude fields is changing and \
218-
file `{}` WILL be excluded in a future Cargo version.\n\
221+
"Pattern matching for Cargo's include/exclude fields has changed and \
222+
file `{}` is now excluded.\n\
219223
See <https://github.com/rust-lang/cargo/issues/4268> for more \
220224
information.",
221225
relative_path.display()
222226
))?;
223227
} else {
224228
self.config.shell().warn(format!(
225-
"Pattern matching for Cargo's include/exclude fields is changing and \
226-
file `{}` WILL NOT be included in a future Cargo version.\n\
229+
"Pattern matching for Cargo's include/exclude fields has changed and \
230+
file `{}` is no longer included.\n\
227231
See <https://github.com/rust-lang/cargo/issues/4268> for more \
228232
information.",
229233
relative_path.display()
230234
))?;
231235
}
232236
} else if no_include_option {
233237
self.config.shell().warn(format!(
234-
"Pattern matching for Cargo's include/exclude fields is changing and \
235-
file `{}` WILL NOT be excluded in a future Cargo version.\n\
238+
"Pattern matching for Cargo's include/exclude fields has changed and \
239+
file `{}` is NOT excluded.\n\
236240
See <https://github.com/rust-lang/cargo/issues/4268> for more \
237241
information.",
238242
relative_path.display()
239243
))?;
240244
} else {
241245
self.config.shell().warn(format!(
242-
"Pattern matching for Cargo's include/exclude fields is changing and \
243-
file `{}` WILL be included in a future Cargo version.\n\
246+
"Pattern matching for Cargo's include/exclude fields has changed and \
247+
file `{}` is now included.\n\
244248
See <https://github.com/rust-lang/cargo/issues/4268> for more \
245249
information.",
246250
relative_path.display()
247251
))?;
248252
}
249253
}
250254

251-
// Update to `ignore_should_package` for Stage 2.
252-
Ok(glob_should_package)
255+
Ok(ignore_should_package)
253256
};
254257

255258
// Attempt Git-prepopulate only if no `include` (see rust-lang/cargo#4135).

src/doc/src/reference/manifest.md

Lines changed: 44 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -73,11 +73,11 @@ examples, etc.
7373

7474
#### The `build` field (optional)
7575

76-
This field specifies a file in the package root which is a [build script][1] for
77-
building native code. More information can be found in the build script
78-
[guide][1].
76+
This field specifies a file in the package root which is a [build script] for
77+
building native code. More information can be found in the [build script
78+
guide][build script].
7979

80-
[1]: reference/build-scripts.html
80+
[build script]: reference/build-scripts.html
8181

8282
```toml
8383
[package]
@@ -121,15 +121,37 @@ may be replaced by docs.rs links.
121121

122122
#### The `exclude` and `include` fields (optional)
123123

124-
You can explicitly specify to Cargo that a set of [globs][globs] should be
125-
ignored or included for the purposes of packaging and rebuilding a package. The
126-
globs specified in the `exclude` field identify a set of files that are not
127-
included when a package is published as well as ignored for the purposes of
128-
detecting when to rebuild a package, and the globs in `include` specify files
129-
that are explicitly included.
130-
131-
If a VCS is being used for a package, the `exclude` field will be seeded with
132-
the VCS’ ignore settings (`.gitignore` for git for example).
124+
You can explicitly specify that a set of file patterns should be ignored or
125+
included for the purposes of packaging. The patterns specified in the
126+
`exclude` field identify a set of files that are not included, and the
127+
patterns in `include` specify files that are explicitly included.
128+
129+
The patterns should be [gitignore]-style patterns. Briefly:
130+
131+
- `foo` matches any file or directory with the name `foo` anywhere in the
132+
package. This is equivalent to the pattern `**/foo`.
133+
- `/foo` matches any file or directory with the name `foo` only in the root of
134+
the package.
135+
- `foo/` matches any *directory* with the name `foo` anywhere in the package.
136+
- Common glob patterns like `*`, `?`, and `[]` are supported:
137+
- `*` matches zero or more characters except `/`. For example, `*.html`
138+
matches any file or directory with the `.html` extension anywhere in the
139+
package.
140+
- `?` matches any character except `/`. For example, `foo?` matches `food`,
141+
but not `foo`.
142+
- `[]` allows for matching a range of characters. For example, `[ab]`
143+
matches either `a` or `b`. `[a-z]` matches letters a through z.
144+
- `**/` prefix matches in any directory. For example, `**/foo/bar` matches the
145+
file or directory `bar` anywhere that is directly under directory `foo`.
146+
- `/**` suffix matches everything inside. For example, `foo/**` matches all
147+
files inside directory `foo`, including all files in subdirectories below
148+
`foo`.
149+
- `/**/` matches zero or more directories. For example, `a/**/b` matches
150+
`a/b`, `a/x/b`, `a/x/y/b`, and so on.
151+
- `!` prefixed patterns are not supported.
152+
153+
If git is being used for a package, the `exclude` field will be seeded with
154+
the `gitignore` settings from the repository.
133155

134156
```toml
135157
[package]
@@ -148,21 +170,14 @@ The options are mutually exclusive: setting `include` will override an
148170
necessary source files may not be included. The package's `Cargo.toml` is
149171
automatically included.
150172

151-
[globs]: https://docs.rs/glob/0.2.11/glob/struct.Pattern.html
152-
153-
#### Migrating to `gitignore`-like pattern matching
173+
The include/exclude list is also used for change tracking in some situations.
174+
For targets built with `rustdoc`, it is used to determine the list of files to
175+
track to determine if the target should be rebuilt. If the package has a
176+
[build script] that does not emit any `rerun-if-*` directives, then the
177+
include/exclude list is used for tracking if the build script should be re-run
178+
if any of those files change.
154179

155-
The current interpretation of these configs is based on UNIX Globs, as
156-
implemented in the [`glob` crate](https://crates.io/crates/glob). We want
157-
Cargo's `include` and `exclude` configs to work as similar to `gitignore` as
158-
possible. [The `gitignore` specification](https://git-scm.com/docs/gitignore) is
159-
also based on Globs, but has a bunch of additional features that enable easier
160-
pattern writing and more control. Therefore, we are migrating the interpretation
161-
for the rules of these configs to use the [`ignore`
162-
crate](https://crates.io/crates/ignore), and treat them each rule as a single
163-
line in a `gitignore` file. See [the tracking
164-
issue](https://github.com/rust-lang/cargo/issues/4268) for more details on the
165-
migration.
180+
[gitignore]: https://git-scm.com/docs/gitignore
166181

167182
#### The `publish` field (optional)
168183

@@ -615,6 +630,8 @@ and also be a member crate of another workspace (contain `package.workspace`).
615630
Most of the time workspaces will not need to be dealt with as `cargo new` and
616631
`cargo init` will handle workspace configuration automatically.
617632

633+
[globs]: https://docs.rs/glob/0.2.11/glob/struct.Pattern.html
634+
618635
#### Virtual Manifest
619636

620637
In workspace manifests, if the `package` table is present, the workspace root

0 commit comments

Comments
 (0)