No bug - Revendor rust dependencies

This commit is contained in:
Servo VCS Sync 2018-04-06 13:23:37 +00:00
parent 41e729e7d1
commit eba1851674
18 changed files with 1411 additions and 400 deletions

18
Cargo.lock generated
View File

@ -1692,11 +1692,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "same-file"
version = "0.1.3"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -1898,7 +1897,7 @@ dependencies = [
"unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-segmentation 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"walkdir 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
"walkdir 2.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -2239,12 +2238,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "walkdir"
version = "1.0.7"
version = "2.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"same-file 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
"same-file 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -2618,7 +2616,7 @@ dependencies = [
"checksum rust-ini 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "22dab655e8122ccb15db25a56852ce62506f1486cdefd37e86371bf34ea8f601"
"checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda"
"checksum safemem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e27a8b19b835f7aea908818e871f5cc3a5a186550c30773be987e155e8163d8f"
"checksum same-file 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d931a44fdaa43b8637009e7632a02adc4f2b2e0733c08caa4cf00e8da4a117a7"
"checksum same-file 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "cfb6eded0b06a0b512c8ddbcf04089138c9b4362c2f696f3c3d76039d68f3637"
"checksum scoped-tls 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f417c22df063e9450888a7561788e9bd46d3bb3c1466435b4eccb903807f147d"
"checksum scopeguard 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c79eb2c3ac4bc2507cda80e7f3ac5b88bd8eae4c0914d5663e6a8933994be918"
"checksum semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a3186ec9e65071a2095434b1f5bb24838d4e8e130f584c790f6033c79943537"
@ -2672,7 +2670,7 @@ dependencies = [
"checksum vec_map 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "887b5b631c2ad01628bbbaa7dd4c869f80d3186688f8d0b6f58774fbe324988c"
"checksum version_check 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6b772017e347561807c1aa192438c5fd74242a670a6cffacc40f2defd1dc069d"
"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
"checksum walkdir 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "bb08f9e670fab86099470b97cd2b252d6527f0b3cc1401acdb595ffc9dd288ff"
"checksum walkdir 2.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "63636bd0eb3d00ccb8b9036381b526efac53caf112b7783b730ab3f8e44da369"
"checksum webidl 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "dc14e4b71f94b5bb4c6d696e3b3be4d2e9ee6750a60870ecae09ff7138a131a7"
"checksum which 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4be6cfa54dab45266e98b5d7be2f8ce959ddd49abd141a05d52dce4b07f803bb"
"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"

View File

@ -1 +1 @@
{"files":{".travis.yml":"6a895f292f66275f93130c18595c210654778e113779143a3d3b14b37979053b","COPYING":"7ca1297d23644e30bd489193a82a33f324e5fe33f25df4195649b91b883df967","Cargo.toml":"6191fe9baeaa414b5339d7c248ed277d0eefc387e1919c5c27eced327f1f63e0","README.md":"dbedb77a4c03aaddce2e907fcbfb0af4ddc1dd6074f48403040e2cb010df9c67","appveyor.yml":"d273c4f1531255fc19b5808f951159c797a934bf444b7a2f0e8adb6d35f2076b","examples/is_same_file.rs":"08a34217f72b7b48e1cdb7490555af15e758e95777bf9d4a1799c652fdcfec14","examples/is_stderr.rs":"a2fbe307c47a3c1da5d83b69524561d780e4f6c05deff3c71cd161dc41c23503","src/lib.rs":"41df53e6e0524025d69f279ddc6a25e80709f7e482e1ddd80bb7cd4e8ac187a5","src/unix.rs":"530b43f42c94791c8860cf94d3f97440f2ba08efc44281e9f4a3df086e2cc770","src/win.rs":"6440fc7a9c1391c9423016f5437b1e925867f172b668124b12d36a5e6f33f053"},"package":"d931a44fdaa43b8637009e7632a02adc4f2b2e0733c08caa4cf00e8da4a117a7"}
{"files":{".travis.yml":"cafb96675fff81a04a3c01278a87480fa45069a3f83bf3ec60089b1ee1973283","COPYING":"7ca1297d23644e30bd489193a82a33f324e5fe33f25df4195649b91b883df967","Cargo.toml":"ce5e3df16b1d2d7b4a6ff8f281105e51bc044d103b7f0007a19dd7fe2bc68d67","README.md":"ac8eb57fecc2fe81dfd97ceb2c6b04db0e0af7a097508d407c248dca51fe38af","appveyor.yml":"d273c4f1531255fc19b5808f951159c797a934bf444b7a2f0e8adb6d35f2076b","examples/is_same_file.rs":"f8fdd8870bf508268dfa0505deaec55bc64fc0e7cd9e527b5a7581a06313b8cb","examples/is_stderr.rs":"3646a0eb120ded24c5fba612ab77866ae987ae8b6d1925a139d3ea572adfa298","src/lib.rs":"682661b425e0d1a5161097171bde840efcae85c8814acdf0231b00b1dfd46e02","src/unix.rs":"f3b74e112d372378dc57c1ac42e64958c9b7d35ea8ac306025387e96178723b5","src/win.rs":"2f588a9dd0ca69bf1699896e7b732b52eaf9159d1fc2a5959bb8c6c4bd72da69"},"package":"cfb6eded0b06a0b512c8ddbcf04089138c9b4362c2f696f3c3d76039d68f3637"}

View File

@ -1,9 +1,17 @@
dist: trusty
language: rust
rust:
- 1.10.0
- stable
- beta
- nightly
matrix:
include:
- os: linux
rust: 1.17.0
- os: linux
rust: stable
- os: linux
rust: beta
- os: linux
rust: nightly
- os: osx
rust: nightly
script:
- cargo build --verbose
- cargo test --verbose

View File

@ -1,20 +1,28 @@
# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
#
# When uploading crates to the registry Cargo will automatically
# "normalize" Cargo.toml files for maximal compatibility
# with all versions of Cargo and also rewrite `path` dependencies
# to registry (e.g. crates.io) dependencies
#
# If you believe there's an error in this file please file an
# issue against the rust-lang/cargo repository. If you're
# editing this file be aware that the upstream Cargo.toml
# will likely look very different (and much more reasonable)
[package]
name = "same-file"
version = "0.1.3" #:version
version = "1.0.2"
authors = ["Andrew Gallant <jamslam@gmail.com>"]
description = """
A simple crate for determining whether two file paths point to the same file.
"""
documentation = "https://docs.rs/same-file"
description = "A simple crate for determining whether two file paths point to the same file.\n"
homepage = "https://github.com/BurntSushi/same-file"
repository = "https://github.com/BurntSushi/same-file"
documentation = "https://docs.rs/same-file"
readme = "README.md"
keywords = ["same", "file", "equal", "inode"]
license = "Unlicense/MIT"
[target.'cfg(windows)'.dependencies]
kernel32-sys = "0.2"
winapi = "0.2"
[dev-dependencies]
rand = "0.3"
repository = "https://github.com/BurntSushi/same-file"
[dev-dependencies.rand]
version = "0.4"
[target."cfg(windows)".dependencies.winapi]
version = "0.3"
features = ["std", "fileapi", "minwindef", "processenv", "winbase"]

View File

@ -19,7 +19,7 @@ Add this to your `Cargo.toml`:
```toml
[dependencies]
same-file = "0.1"
same-file = "1"
```
and this to your crate root:

View File

@ -1,7 +1,13 @@
extern crate same_file;
use std::error::Error;
use same_file::is_same_file;
fn main() {
assert!(is_same_file("/bin/sh", "/usr/bin/sh").unwrap());
fn try_main() -> Result<(), Box<Error>> {
assert!(is_same_file("/bin/sh", "/usr/bin/sh")?);
Ok(())
}
fn main() {
try_main().unwrap();
}

View File

@ -20,9 +20,9 @@ fn run() -> io::Result<()> {
"examples/is_stderr.rs",
"examples/stderr",
];
let stderr_handle = try!(Handle::stderr());
let stderr_handle = Handle::stderr()?;
for candidate in candidates {
let handle = try!(Handle::from_path(candidate));
let handle = Handle::from_path(candidate)?;
if stderr_handle == handle {
println!("{:?} is stderr!", candidate);
} else {

View File

@ -2,54 +2,72 @@
This crate provides a safe and simple **cross platform** way to determine
whether two file paths refer to the same file or directory.
Most uses of this crate should be limited to the top-level `is_same_file`
Most uses of this crate should be limited to the top-level [`is_same_file`]
function, which takes two file paths and returns true if they refer to the
same file or directory:
```rust,no_run
# fn example() -> ::std::io::Result<()> {
# use std::error::Error;
use same_file::is_same_file;
assert!(try!(is_same_file("/bin/sh", "/usr/bin/sh")));
# Ok(()) } example().unwrap();
# fn try_main() -> Result<(), Box<Error>> {
assert!(is_same_file("/bin/sh", "/usr/bin/sh")?);
# Ok(())
# }
#
# fn main() {
# try_main().unwrap();
# }
```
Additionally, this crate provides a `Handle` type that permits a more efficient
Additionally, this crate provides a [`Handle`] type that permits a more efficient
equality check depending on your access pattern. For example, if one wanted to
checked whether any path in a list of paths corresponded to the process' stdout
check whether any path in a list of paths corresponded to the process' stdout
handle, then one could build a handle once for stdout. The equality check for
each file in the list then only requires one stat call instead of two. The code
might look like this:
```rust,no_run
# fn example() -> ::std::io::Result<()> {
# use std::error::Error;
use same_file::Handle;
# fn try_main() -> Result<(), Box<Error>> {
let candidates = &[
"examples/is_same_file.rs",
"examples/is_stderr.rs",
"examples/stderr",
];
let stdout_handle = try!(Handle::stdout());
let stdout_handle = Handle::stdout()?;
for candidate in candidates {
let handle = try!(Handle::from_path(candidate));
let handle = Handle::from_path(candidate)?;
if stdout_handle == handle {
println!("{:?} is stdout!", candidate);
} else {
println!("{:?} is NOT stdout!", candidate);
}
}
# Ok(()) } example().unwrap();
# Ok(())
# }
#
# fn main() {
# try_main().unwrap();
# }
```
See `examples/is_stderr.rs` for a runnable example. Compare the output of
`cargo run is_stderr 2> examples/stderr` and `cargo run is_stderr`.
See [`examples/is_stderr.rs`] for a runnable example and compare the output of:
- `cargo run is_stderr 2> examples/stderr` and
- `cargo run is_stderr`.
[`is_same_file`]: fn.is_same_file.html
[`Handle`]: struct.Handle.html
[`examples/is_stderr.rs`]: https://github.com/BurntSushi/same-file/blob/master/examples/is_same_file.rs
*/
#![doc(html_root_url = "https://docs.rs/same-file/1.0.0")]
#![deny(missing_docs)]
#[cfg(windows)]
extern crate kernel32;
#[cfg(windows)]
extern crate winapi;
@ -75,58 +93,251 @@ mod win;
///
/// A handle consumes an open file resource as long as it exists.
///
/// Note that it's possible for comparing two handles to produce a false
/// positive on some platforms. Namely, two handles can compare equal even if
/// the two handles *don't* point to the same file.
/// Equality is determined by comparing inode numbers on Unix and a combination
/// of identifier, volume serial, and file size on Windows. Note that it's
/// possible for comparing two handles to produce a false positive on some
/// platforms. Namely, two handles can compare equal even if the two handles
/// *don't* point to the same file. Check the [source] for specific
/// implementation details.
///
/// [source]: https://github.com/BurntSushi/same-file/tree/master/src
#[derive(Debug, Eq, PartialEq)]
pub struct Handle(imp::Handle);
impl Handle {
/// Construct a handle from a path.
///
/// Note that the underlying `File` is opened in read-only mode on all
/// Note that the underlying [`File`] is opened in read-only mode on all
/// platforms.
///
/// [`File`]: https://doc.rust-lang.org/std/fs/struct.File.html
///
/// # Errors
/// This method will return an [`io::Error`] if the path cannot
/// be opened, or the file's metadata cannot be obtained.
/// The most common reasons for this are: the path does not
/// exist, or there were not enough permissions.
///
/// [`io::Error`]: https://doc.rust-lang.org/std/io/struct.Error.html
///
/// # Examples
/// Check that two paths are not the same file:
///
/// ```rust,no_run
/// # use std::error::Error;
/// use same_file::Handle;
///
/// # fn try_main() -> Result<(), Box<Error>> {
/// let source = Handle::from_path("./source")?;
/// let target = Handle::from_path("./target")?;
/// assert_ne!(source, target, "The files are the same.");
/// # Ok(())
/// # }
/// #
/// # fn main() {
/// # try_main().unwrap();
/// # }
/// ```
pub fn from_path<P: AsRef<Path>>(p: P) -> io::Result<Handle> {
imp::Handle::from_path(p).map(Handle)
}
/// Construct a handle from a file.
///
/// # Errors
/// This method will return an [`io::Error`] if the metadata for
/// the given [`File`] cannot be obtained.
///
/// [`io::Error`]: https://doc.rust-lang.org/std/io/struct.Error.html
/// [`File`]: https://doc.rust-lang.org/std/fs/struct.File.html
///
/// # Examples
/// Check that two files are not in fact the same file:
///
/// ```rust,no_run
/// # use std::error::Error;
/// # use std::fs::File;
/// use same_file::Handle;
///
/// # fn try_main() -> Result<(), Box<Error>> {
/// let source = File::open("./source")?;
/// let target = File::open("./target")?;
///
/// assert_ne!(
/// Handle::from_file(source)?,
/// Handle::from_file(target)?,
/// "The files are the same."
/// );
/// # Ok(())
/// # }
/// #
/// # fn main() {
/// # try_main().unwrap();
/// # }
/// ```
pub fn from_file(file: File) -> io::Result<Handle> {
imp::Handle::from_file(file).map(Handle)
}
/// Construct a handle from stdin.
///
/// # Errors
/// This method will return an [`io::Error`] if stdin cannot
/// be opened due to any I/O-related reason.
///
/// [`io::Error`]: https://doc.rust-lang.org/std/io/struct.Error.html
///
/// # Examples
///
/// ```rust
/// # use std::error::Error;
/// use same_file::Handle;
///
/// # fn try_main() -> Result<(), Box<Error>> {
/// let stdin = Handle::stdin()?;
/// let stdout = Handle::stdout()?;
/// let stderr = Handle::stderr()?;
///
/// if stdin == stdout {
/// println!("stdin == stdout");
/// }
/// if stdin == stderr {
/// println!("stdin == stderr");
/// }
/// if stdout == stderr {
/// println!("stdout == stderr");
/// }
/// #
/// # Ok(())
/// # }
/// #
/// # fn main() {
/// # try_main().unwrap();
/// # }
/// ```
///
/// The output differs depending on the platform.
///
/// On Linux:
///
/// ```text
/// $ ./example
/// stdin == stdout
/// stdin == stderr
/// stdout == stderr
/// $ ./example > result
/// $ cat result
/// stdin == stderr
/// $ ./example > result 2>&1
/// $ cat result
/// stdout == stderr
/// ```
///
/// Windows:
///
/// ```text
/// > example
/// > example > result 2>&1
/// > type result
/// stdout == stderr
/// ```
pub fn stdin() -> io::Result<Handle> {
imp::Handle::stdin().map(Handle)
}
/// Construct a handle from stdout.
///
/// # Errors
/// This method will return an [`io::Error`] if stdout cannot
/// be opened due to any I/O-related reason.
///
/// [`io::Error`]: https://doc.rust-lang.org/std/io/struct.Error.html
///
/// # Examples
/// See the example for [`stdin()`].
///
/// [`stdin()`]: #method.stdin
pub fn stdout() -> io::Result<Handle> {
imp::Handle::stdout().map(Handle)
}
/// Construct a handle from stderr.
///
/// # Errors
/// This method will return an [`io::Error`] if stderr cannot
/// be opened due to any I/O-related reason.
///
/// [`io::Error`]: https://doc.rust-lang.org/std/io/struct.Error.html
///
/// # Examples
/// See the example for [`stdin()`].
///
/// [`stdin()`]: #method.stdin
pub fn stderr() -> io::Result<Handle> {
imp::Handle::stderr().map(Handle)
}
/// Return a reference to the underlying file.
///
/// # Examples
/// Ensure that the target file is not the same as the source one,
/// and copy the data to it:
///
/// ```rust,no_run
/// # use std::error::Error;
/// use std::io::prelude::*;
/// use std::io::Write;
/// use std::fs::File;
/// use same_file::Handle;
///
/// # fn try_main() -> Result<(), Box<Error>> {
/// let source = File::open("source")?;
/// let target = File::create("target")?;
///
/// let source_handle = Handle::from_file(source)?;
/// let mut target_handle = Handle::from_file(target)?;
/// assert_ne!(source_handle, target_handle, "The files are the same.");
///
/// let mut source = source_handle.as_file();
/// let target = target_handle.as_file_mut();
///
/// let mut buffer = Vec::new();
/// // data copy is simplified for the purposes of the example
/// source.read_to_end(&mut buffer)?;
/// target.write_all(&buffer)?;
/// #
/// # Ok(())
/// # }
/// #
/// # fn main() {
/// # try_main().unwrap();
/// # }
/// ```
pub fn as_file(&self) -> &File {
self.0.as_file()
}
/// Return a mutable reference to the underlying file.
///
/// # Examples
/// See the example for [`as_file()`].
///
/// [`as_file()`]: #method.as_file
pub fn as_file_mut(&mut self) -> &mut File {
self.0.as_file_mut()
}
/// Return the underlying device number of this handle.
///
/// Note that this only works on unix platforms.
#[cfg(any(target_os = "redox", unix))]
pub fn dev(&self) -> u64 {
self.0.dev()
}
/// Return the underlying inode number of this handle.
///
/// Note that this only works on unix platforms.
#[cfg(any(target_os = "redox", unix))]
pub fn ino(&self) -> u64 {
self.0.ino()
@ -135,12 +346,15 @@ impl Handle {
/// Returns true if the two file paths may correspond to the same file.
///
/// If there was a problem accessing either file path, then an error is
/// returned.
///
/// Note that it's possible for this to produce a false positive on some
/// platforms. Namely, this can return true even if the two file paths *don't*
/// resolve to the same file.
/// # Errors
/// This function will return an [`io::Error`] if any of the two paths cannot
/// be opened. The most common reasons for this are: the path does not exist,
/// or there were not enough permissions.
///
/// [`io::Error`]: https://doc.rust-lang.org/std/io/struct.Error.html
///
/// # Example
///
@ -153,7 +367,7 @@ pub fn is_same_file<P, Q>(
path1: P,
path2: Q,
) -> io::Result<bool> where P: AsRef<Path>, Q: AsRef<Path> {
Ok(try!(Handle::from_path(path1)) == try!(Handle::from_path(path2)))
Ok(Handle::from_path(path1)? == Handle::from_path(path2)?)
}
#[cfg(test)]
@ -301,4 +515,16 @@ mod tests {
soft_link_dir(dir.join("a"), dir.join("alink")).unwrap();
assert!(is_same_file(dir.join("a"), dir.join("alink")).unwrap());
}
#[test]
fn test_send() {
fn assert_send<T: Send>() {}
assert_send::<super::Handle>();
}
#[test]
fn test_sync() {
fn assert_sync<T: Sync>() {}
assert_sync::<super::Handle>();
}
}

View File

@ -1,4 +1,5 @@
use std::fs::{File, OpenOptions};
use std::hash::{Hash, Hasher};
use std::io;
use std::os::unix::fs::MetadataExt;
use std::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd};
@ -17,6 +18,8 @@ pub struct Handle {
impl Drop for Handle {
fn drop(&mut self) {
if self.is_std {
// unwrap() will not panic. Since we were able to open an
// std stream successfully, then `file` is guaranteed to be Some()
self.file.take().unwrap().into_raw_fd();
}
}
@ -32,23 +35,34 @@ impl PartialEq for Handle {
impl AsRawFd for ::Handle {
fn as_raw_fd(&self) -> RawFd {
// unwrap() will not panic. Since we were able to open the
// file successfully, then `file` is guaranteed to be Some()
self.0.file.as_ref().take().unwrap().as_raw_fd()
}
}
impl IntoRawFd for ::Handle {
fn into_raw_fd(mut self) -> RawFd {
// unwrap() will not panic. Since we were able to open the
// file successfully, then `file` is guaranteed to be Some()
self.0.file.take().unwrap().into_raw_fd()
}
}
impl Hash for Handle {
fn hash<H: Hasher>(&self, state: &mut H) {
self.dev.hash(state);
self.ino.hash(state);
}
}
impl Handle {
pub fn from_path<P: AsRef<Path>>(p: P) -> io::Result<Handle> {
Handle::from_file(try!(OpenOptions::new().read(true).open(p)))
Handle::from_file(OpenOptions::new().read(true).open(p)?)
}
pub fn from_file(file: File) -> io::Result<Handle> {
let md = try!(file.metadata());
let md = file.metadata()?;
Ok(Handle {
file: Some(file),
is_std: false,
@ -77,10 +91,14 @@ impl Handle {
}
pub fn as_file(&self) -> &File {
// unwrap() will not panic. Since we were able to open the
// file successfully, then `file` is guaranteed to be Some()
self.file.as_ref().take().unwrap()
}
pub fn as_file_mut(&mut self) -> &mut File {
// unwrap() will not panic. Since we were able to open the
// file successfully, then `file` is guaranteed to be Some()
self.file.as_mut().take().unwrap()
}

View File

@ -1,4 +1,5 @@
use std::fs::{File, OpenOptions};
use std::hash::{Hash, Hasher};
use std::io;
use std::mem;
use std::os::windows::fs::OpenOptionsExt;
@ -7,10 +8,13 @@ use std::os::windows::io::{
};
use std::path::Path;
use kernel32::{GetFileInformationByHandle, GetStdHandle};
use winapi::fileapi::BY_HANDLE_FILE_INFORMATION;
use winapi::minwindef::DWORD;
use winapi::winbase::{
use winapi::shared::minwindef::DWORD;
use winapi::um::fileapi::{
BY_HANDLE_FILE_INFORMATION,
GetFileInformationByHandle,
};
use winapi::um::processenv::GetStdHandle;
use winapi::um::winbase::{
FILE_FLAG_BACKUP_SEMANTICS,
STD_INPUT_HANDLE, STD_OUTPUT_HANDLE, STD_ERROR_HANDLE,
};
@ -24,7 +28,7 @@ use winapi::winbase::{
// https://msdn.microsoft.com/en-us/library/windows/desktop/aa363788(v=vs.85).aspx
//
// It gets worse. It appears that the index numbers are not always
// guaranteed to be unqiue. Namely, ReFS uses 128 bit numbers for unique
// guaranteed to be unique. Namely, ReFS uses 128 bit numbers for unique
// identifiers. This requires a distinct syscall to get `FILE_ID_INFO`
// documented here:
// https://msdn.microsoft.com/en-us/library/windows/desktop/hh802691(v=vs.85).aspx
@ -65,7 +69,7 @@ pub struct Handle {
key: Option<Key>,
}
#[derive(Debug, Eq, PartialEq)]
#[derive(Debug, Eq, PartialEq, Hash)]
struct Key {
volume: DWORD,
idx_high: DWORD,
@ -75,6 +79,8 @@ struct Key {
impl Drop for Handle {
fn drop(&mut self) {
if self.is_std {
// unwrap() will not panic. Since we were able to open an
// std stream successfully, then `file` is guaranteed to be Some()
self.file.take().unwrap().into_raw_handle();
}
}
@ -84,7 +90,11 @@ impl Eq for Handle {}
impl PartialEq for Handle {
fn eq(&self, other: &Handle) -> bool {
if self.key.is_none() || other.key.is_none() {
// Need this branch to satisfy `Eq` since `Handle`s with `key.is_none()`
// wouldn't otherwise.
if self as *const Handle == other as *const Handle {
return true;
} else if self.key.is_none() || other.key.is_none() {
return false;
}
self.key == other.key
@ -93,23 +103,33 @@ impl PartialEq for Handle {
impl AsRawHandle for ::Handle {
fn as_raw_handle(&self) -> RawHandle {
// unwrap() will not panic. Since we were able to open the
// file successfully, then `file` is guaranteed to be Some()
self.0.file.as_ref().take().unwrap().as_raw_handle()
}
}
impl IntoRawHandle for ::Handle {
fn into_raw_handle(mut self) -> RawHandle {
// unwrap() will not panic. Since we were able to open the
// file successfully, then `file` is guaranteed to be Some()
self.0.file.take().unwrap().into_raw_handle()
}
}
impl Hash for Handle {
fn hash<H: Hasher>(&self, state: &mut H) {
self.key.hash(state);
}
}
impl Handle {
pub fn from_path<P: AsRef<Path>>(p: P) -> io::Result<Handle> {
let file = try!(OpenOptions::new()
let file = OpenOptions::new()
.read(true)
// Necessary in order to support opening directory paths.
.custom_flags(FILE_FLAG_BACKUP_SEMANTICS)
.open(p));
.open(p)?;
Handle::from_file(file)
}
@ -164,10 +184,14 @@ impl Handle {
}
pub fn as_file(&self) -> &File {
// unwrap() will not panic. Since we were able to open the
// file successfully, then `file` is guaranteed to be Some()
self.file.as_ref().take().unwrap()
}
pub fn as_file_mut(&mut self) -> &mut File {
// unwrap() will not panic. Since we were able to open the
// file successfully, then `file` is guaranteed to be Some()
self.file.as_mut().take().unwrap()
}
}

View File

@ -1 +1 @@
{"files":{".travis.yml":"3865292ac0afca5fce05632ec5e4f0a2f6a13e612ecc46cc0dd96d8c4c73ca67","COPYING":"01c266bced4a434da0051174d6bee16a4c82cf634e2679b6155d40d75012390f","Cargo.toml":"4324e7cfcc4ec1897f1de6471e4ad7dfeeea331bbbfc06e14f2550b17b0a3e02","LICENSE-MIT":"0f96a83840e146e43c0ec96a22ec1f392e0680e6c1226e6f3ba87e0740af850f","Makefile":"a45a128685a2ae7d4fa39d310786674417ee113055ef290a11f88002285865fc","README.md":"641500136e1777a9a1e9a9394f33a7ff17590ac7d951c6530130a52548b1d925","UNLICENSE":"7e12e5df4bae12cb21581ba157ced20e1986a0508dd10d0e8a4ab9a4cf94e85c","appveyor.yml":"77bbcc4b6f8f44eadb160ae46c9ac2e277775a57869aa7b8f59120ea2eb7a1c2","compare/nftw.c":"6b900b0ac78ce8ece1995f834b194fa14d87d744cabba8f475f0e10b21722c56","compare/walk.py":"d49e26d0b8b2b201d00f2f46bf1f9db46f873c27332da679c9a7adbbf54462d2","ctags.rust":"3d128d3cc59f702e68953ba2fe6c3f46bc6991fc575308db060482d5da0c79f3","examples/walkdir.rs":"8c86cf2e8b64d89dc951f3e1b0e119c2a42f113a7459523f826fadcb9419ba60","session.vim":"95cb1d7caf0ff7fbe76ec911988d908ddd883381c925ba64b537695bc9f021c4","src/lib.rs":"af1d35e968c61c061cf76c336ed2bbe8ab0e4d4d3fd63c9f53116a36a0fd0f7b","src/tests.rs":"34d9bb48db5ec2f83bdcad071e5d332cc16635fd3fd25f6452a7eeefe6f09da8"},"package":"bb08f9e670fab86099470b97cd2b252d6527f0b3cc1401acdb595ffc9dd288ff"}
{"files":{".travis.yml":"b3d3a96db9f091623de082126dd8f434c86c8a93bfa841183c635c5a5658bdee","COPYING":"01c266bced4a434da0051174d6bee16a4c82cf634e2679b6155d40d75012390f","Cargo.toml":"eb9bd73ac96889c92fac322a899a9a9c59484532c5957fce45aee472691aaacf","LICENSE-MIT":"0f96a83840e146e43c0ec96a22ec1f392e0680e6c1226e6f3ba87e0740af850f","Makefile":"a45a128685a2ae7d4fa39d310786674417ee113055ef290a11f88002285865fc","README.md":"189d8ae0bb722a97844d812ebed0f3c90a96a33652313adf8cfc8cba081ba8fe","UNLICENSE":"7e12e5df4bae12cb21581ba157ced20e1986a0508dd10d0e8a4ab9a4cf94e85c","appveyor.yml":"77bbcc4b6f8f44eadb160ae46c9ac2e277775a57869aa7b8f59120ea2eb7a1c2","compare/nftw.c":"6b900b0ac78ce8ece1995f834b194fa14d87d744cabba8f475f0e10b21722c56","compare/walk.py":"d49e26d0b8b2b201d00f2f46bf1f9db46f873c27332da679c9a7adbbf54462d2","ctags.rust":"3d128d3cc59f702e68953ba2fe6c3f46bc6991fc575308db060482d5da0c79f3","examples/walkdir.rs":"004a004cc3992efba6f8510a34d3d471a176ae7a317716c3a89edfec3e3d252d","session.vim":"95cb1d7caf0ff7fbe76ec911988d908ddd883381c925ba64b537695bc9f021c4","src/lib.rs":"bd4b9b1148768f2f9f857a63858e5bda0d85313ad1352fe5d6ab0273704c1272","src/tests.rs":"cfeb9918f1c8a76e4b3a30439534359d4a29d1576d510ab8cbc7d1f26389477f","src/unix.rs":"330a017a8da231c4c72112d319e4089d014fe4b4cbc3f5665334b39968fb6262"},"package":"63636bd0eb3d00ccb8b9036381b526efac53caf112b7783b730ab3f8e44da369"}

View File

@ -1,9 +1,16 @@
language: rust
rust:
- 1.10.0
- stable
- beta
- nightly
matrix:
include:
- os: linux
rust: 1.17.0
- os: linux
rust: stable
- os: linux
rust: beta
- os: linux
rust: nightly
- os: osx
rust: nightly
script:
- cargo build --verbose
- cargo test --verbose

View File

@ -1,24 +1,49 @@
# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
#
# When uploading crates to the registry Cargo will automatically
# "normalize" Cargo.toml files for maximal compatibility
# with all versions of Cargo and also rewrite `path` dependencies
# to registry (e.g. crates.io) dependencies
#
# If you believe there's an error in this file please file an
# issue against the rust-lang/cargo repository. If you're
# editing this file be aware that the upstream Cargo.toml
# will likely look very different (and much more reasonable)
[package]
name = "walkdir"
version = "1.0.7" #:version
version = "2.1.4"
authors = ["Andrew Gallant <jamslam@gmail.com>"]
description = "Recursively walk a directory."
documentation = "https://docs.rs/walkdir/"
homepage = "https://github.com/BurntSushi/walkdir"
repository = "https://github.com/BurntSushi/walkdir"
documentation = "https://docs.rs/walkdir/"
readme = "README.md"
keywords = ["directory", "recursive", "walk", "iterator"]
categories = ["filesystem"]
license = "Unlicense/MIT"
repository = "https://github.com/BurntSushi/walkdir"
[dependencies.same-file]
version = "1"
[dev-dependencies.docopt]
version = "0.8"
[dependencies]
same-file = "0.1.1"
[dev-dependencies.quickcheck]
version = "0.6"
default-features = false
[target.'cfg(windows)'.dependencies]
kernel32-sys = "0.2"
winapi = "0.2"
[dev-dependencies.rand]
version = "0.4"
[dev-dependencies]
docopt = "0.7"
quickcheck = { version = "0.4", default-features = false }
rand = "0.3"
rustc-serialize = "0.3"
[dev-dependencies.serde]
version = "1"
[dev-dependencies.serde_derive]
version = "1"
[target."cfg(windows)".dependencies.winapi]
version = "0.3"
features = ["std", "winnt"]
[badges.appveyor]
repository = "BurntSushi/walkdir"
[badges.travis-ci]
repository = "BurntSushi/walkdir"

View File

@ -22,7 +22,7 @@ To use this crate, add `walkdir` as a dependency to your project's
```
[dependencies]
walkdir = "1"
walkdir = "2"
```
### Example
@ -70,7 +70,7 @@ This uses the `filter_entry` iterator adapter to avoid yielding hidden files
and directories efficiently:
```rust,no_run
use walkdir::{DirEntry, WalkDir, WalkDirIterator};
use walkdir::{DirEntry, WalkDir};
fn is_hidden(entry: &DirEntry) -> bool {
entry.file_name()

View File

@ -1,5 +1,7 @@
extern crate docopt;
extern crate rustc_serialize;
extern crate serde;
#[macro_use]
extern crate serde_derive;
extern crate walkdir;
use std::io::{self, Write};
@ -20,9 +22,10 @@ Options:
--tree Show output as a tree.
--sort Sort the output.
-q, --ignore-errors Ignore errors.
-d, --depth Show directory's contents before the directory itself.
";
#[derive(Debug, RustcDecodable)]
#[derive(Debug, Deserialize)]
#[allow(dead_code)]
struct Args {
arg_dir: Option<String>,
@ -33,23 +36,28 @@ struct Args {
flag_tree: bool,
flag_ignore_errors: bool,
flag_sort: bool,
flag_depth: bool,
}
macro_rules! wout { ($($tt:tt)*) => { {writeln!($($tt)*)}.unwrap() } }
fn main() {
let args: Args = Docopt::new(USAGE).and_then(|d| d.decode())
.unwrap_or_else(|e| e.exit());
let args: Args = Docopt::new(USAGE)
.and_then(|d| d.deserialize())
.unwrap_or_else(|e| e.exit());
let mind = args.flag_min_depth.unwrap_or(0);
let maxd = args.flag_max_depth.unwrap_or(::std::usize::MAX);
let dir = args.arg_dir.clone().unwrap_or(".".to_owned());
let mut walkdir = WalkDir::new(dir)
.max_open(args.flag_fd_max)
.follow_links(args.flag_follow_links)
.min_depth(mind)
.max_depth(maxd);
.max_open(args.flag_fd_max)
.follow_links(args.flag_follow_links)
.min_depth(mind)
.max_depth(maxd);
if args.flag_sort {
walkdir = walkdir.sort_by(|a,b| a.cmp(b));
walkdir = walkdir.sort_by(|a,b| a.file_name().cmp(b.file_name()));
}
if args.flag_depth {
walkdir = walkdir.contents_first(true)
}
let it = walkdir.into_iter();
let mut out = io::BufWriter::new(io::stdout());

File diff suppressed because it is too large Load Diff

View File

@ -1,14 +1,16 @@
#![cfg_attr(windows, allow(dead_code, unused_imports))]
use std::cmp;
use std::env;
use std::fs::{self, File};
use std::io;
use std::path::{Path, PathBuf};
use std::collections::HashMap;
use quickcheck::{Arbitrary, Gen, QuickCheck, StdGen};
use rand::{self, Rng};
use super::{DirEntry, WalkDir, WalkDirIterator, Iter, Error, ErrorInner};
use super::{DirEntry, WalkDir, IntoIter, Error, ErrorInner};
#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
enum Tree {
@ -58,6 +60,41 @@ impl Tree {
Ok(stack.pop().unwrap())
}
fn from_walk_with_contents_first<P, F>(
p: P,
f: F,
) -> io::Result<Tree>
where P: AsRef<Path>, F: FnOnce(WalkDir) -> WalkDir {
let mut contents_of_dir_at_depth = HashMap::new();
let mut min_depth = ::std::usize::MAX;
let top_level_path = p.as_ref().to_path_buf();
for result in f(WalkDir::new(p).contents_first(true)) {
let dentry = try!(result);
let tree =
if dentry.file_type().is_dir() {
let any_contents = contents_of_dir_at_depth.remove(
&(dentry.depth+1));
Tree::Dir(pb(dentry.file_name()), any_contents.unwrap_or_default())
} else {
if dentry.file_type().is_symlink() {
let src = try!(dentry.path().read_link());
let dst = pb(dentry.file_name());
let dir = dentry.path().is_dir();
Tree::Symlink { src: src, dst: dst, dir: dir }
} else {
Tree::File(pb(dentry.file_name()))
}
};
contents_of_dir_at_depth.entry(
dentry.depth).or_insert(vec!()).push(tree);
min_depth = cmp::min(min_depth, dentry.depth);
}
Ok(Tree::Dir(top_level_path,
contents_of_dir_at_depth.remove(&min_depth)
.unwrap_or_default()))
}
fn name(&self) -> &Path {
match *self {
Tree::Dir(ref pb, _) => pb,
@ -235,7 +272,7 @@ enum WalkEvent {
struct WalkEventIter {
depth: usize,
it: Iter,
it: IntoIter,
next: Option<Result<DirEntry, Error>>,
}
@ -299,10 +336,13 @@ fn tmpdir() -> TempDir {
}
fn dir_setup_with<F>(t: &Tree, f: F) -> (TempDir, Tree)
where F: FnOnce(WalkDir) -> WalkDir {
where F: Fn(WalkDir) -> WalkDir {
let tmp = tmpdir();
t.create_in(tmp.path()).unwrap();
let got = Tree::from_walk_with(tmp.path(), f).unwrap();
let got = Tree::from_walk_with(tmp.path(), &f).unwrap();
let got_cf = Tree::from_walk_with_contents_first(tmp.path(), &f).unwrap();
assert_eq!(got, got_cf);
(tmp, got.unwrap_singleton().unwrap_singleton())
}
@ -556,6 +596,10 @@ fn walk_dir_min_depth_2() {
exp.create_in(tmp.path()).unwrap();
let got = Tree::from_walk_with(tmp.path(), |wd| wd.min_depth(2))
.unwrap().unwrap_dir();
let got_cf = Tree::from_walk_with_contents_first(
tmp.path(), |wd| wd.min_depth(2))
.unwrap().unwrap_dir();
assert_eq!(got, got_cf);
assert_tree_eq!(exp, td("foo", got));
}
@ -571,6 +615,10 @@ fn walk_dir_min_depth_3() {
let got = Tree::from_walk_with(tmp.path(), |wd| wd.min_depth(3))
.unwrap().unwrap_dir();
assert_eq!(vec![tf("xyz")], got);
let got_cf = Tree::from_walk_with_contents_first(
tmp.path(), |wd| wd.min_depth(3))
.unwrap().unwrap_dir();
assert_eq!(got, got_cf);
}
#[test]
@ -615,6 +663,10 @@ fn walk_dir_min_max_depth() {
let got = Tree::from_walk_with(tmp.path(),
|wd| wd.min_depth(2).max_depth(2))
.unwrap().unwrap_dir();
let got_cf = Tree::from_walk_with_contents_first(tmp.path(),
|wd| wd.min_depth(2).max_depth(2))
.unwrap().unwrap_dir();
assert_eq!(got, got_cf);
assert_tree_eq!(
td("foo", vec![tf("bar"), td("abc", vec![]), tf("baz")]),
td("foo", got));
@ -709,13 +761,16 @@ fn walk_dir_sort() {
let tmp_path = tmp.path();
let tmp_len = tmp_path.to_str().unwrap().len();
exp.create_in(tmp_path).unwrap();
let it = WalkDir::new(tmp_path).sort_by(|a,b| a.cmp(b)).into_iter();
let it = WalkDir::new(tmp_path)
.sort_by(|a,b| a.file_name().cmp(b.file_name()))
.into_iter();
let got = it.map(|d| {
let path = d.unwrap();
let path = &path.path().to_str().unwrap()[tmp_len..];
path.replace("\\", "/")
}).collect::<Vec<String>>();
assert_eq!(got,
assert_eq!(
got,
["", "/foo", "/foo/abc", "/foo/abc/fit", "/foo/bar", "/foo/faz"]);
}
@ -730,13 +785,31 @@ fn walk_dir_sort_small_fd_max() {
let tmp_path = tmp.path();
let tmp_len = tmp_path.to_str().unwrap().len();
exp.create_in(tmp_path).unwrap();
let it =
WalkDir::new(tmp_path).max_open(1).sort_by(|a,b| a.cmp(b)).into_iter();
let it = WalkDir::new(tmp_path)
.max_open(1)
.sort_by(|a,b| a.file_name().cmp(b.file_name()))
.into_iter();
let got = it.map(|d| {
let path = d.unwrap();
let path = &path.path().to_str().unwrap()[tmp_len..];
path.replace("\\", "/")
}).collect::<Vec<String>>();
assert_eq!(got,
assert_eq!(
got,
["", "/foo", "/foo/abc", "/foo/abc/fit", "/foo/bar", "/foo/faz"]);
}
#[test]
fn walk_dir_send_sync_traits() {
use FilterEntry;
fn assert_send<T: Send>() {}
fn assert_sync<T: Sync>() {}
assert_send::<WalkDir>();
assert_sync::<WalkDir>();
assert_send::<IntoIter>();
assert_sync::<IntoIter>();
assert_send::<FilterEntry<IntoIter, u8>>();
assert_sync::<FilterEntry<IntoIter, u8>>();
}

16
third_party/rust/walkdir/src/unix.rs vendored Normal file
View File

@ -0,0 +1,16 @@
use DirEntry;
/// Unix-specific extension methods for `walkdir::DirEntry`
pub trait DirEntryExt {
/// Returns the underlying `d_ino` field in the contained `dirent`
/// structure.
fn ino(&self) -> u64;
}
impl DirEntryExt for DirEntry {
/// Returns the underlying `d_ino` field in the contained `dirent`
/// structure.
fn ino(&self) -> u64 {
self.ino
}
}