summaryrefslogtreecommitdiffstats
path: root/src/feature
diff options
context:
space:
mode:
authorBen S <ogham@bsago.me>2015-04-23 13:00:34 +0100
committerBen S <ogham@bsago.me>2015-04-23 13:00:34 +0100
commitadbaa51cb9421df43625b96ea3ea39b455fd5ee4 (patch)
tree769e5cc63ed3d5759743420a95520e2ccbb90fab /src/feature
parenteee49ecefea05025f94193d487d2dae561a8a8f1 (diff)
Use new io + path + fs libraries (LOTS OF CHANGES)
Exa now uses the new IO, Path, and Filesystem libraries that have been out for a while now. Unfortunately, the new libraries don't *entirely* cover the range of the old libraries just yet: in particular, to become more cross-platform, the data in `UnstableFileStat` isn't available in the Unix `MetadataExt` yet. Much of this is contained in rust-lang/rfcs#1044 (which is due to be implemented in rust-lang/rust#14711), but it's not *entirely* there yet. As such, this commits a serious loss of functionality: no symlink viewing, no hard links or blocks, or users or groups. Also, some of the code could now be optimised. I just wanted to commit this to sort out most of the 'teething problems' of having a different path system in advance. Here's an example problem that took ages to fix for you, just because you read this far: when I first got exa to compile, it worked mostly fine, except calling `exa` by itself didn't list the current directory. I traced where the command-line options were being generated, to where files and directories were sorted, to where the threads were spawned... and the problem turned out to be that it was using the full path as the file name, rather than just the last component, and these paths happened to begin with `.`, so it thought they were dotfiles.
Diffstat (limited to 'src/feature')
-rw-r--r--src/feature/git.rs25
-rw-r--r--src/feature/xattr_darwin.rs33
-rw-r--r--src/feature/xattr_linux.rs31
3 files changed, 38 insertions, 51 deletions
diff --git a/src/feature/git.rs b/src/feature/git.rs
index cc8a033..0d1fb23 100644
--- a/src/feature/git.rs
+++ b/src/feature/git.rs
@@ -1,5 +1,4 @@
-use std::old_path::GenericPath;
-use std::old_path::posix::Path;
+use std::path::{Path, PathBuf};
use ansi_term::{ANSIString, ANSIStrings};
use ansi_term::Colour::*;
@@ -9,7 +8,7 @@ use file::GREY;
/// Container of Git statuses for all the files in this folder's Git repository.
pub struct Git {
- statuses: Vec<(Path, git2::Status)>,
+ statuses: Vec<(PathBuf, git2::Status)>,
}
impl Git {
@@ -17,30 +16,23 @@ impl Git {
/// Discover a Git repository on or above this directory, scanning it for
/// the files' statuses if one is found.
pub fn scan(path: &Path) -> Result<Git, git2::Error> {
- use std::os::unix::ffi::OsStrExt;
- use std::ffi::AsOsStr;
-
- // TODO: libgit2-rs uses the new Path module, but exa still uses the
- // old_path one, and will have to continue to do so until the new IO
- // module gets a bit more developed. So we have to turn Paths into
- // old_path::Paths. Yes, this is hacky, but hopefully temporary.
- let new_path = path.as_os_str();
- let repo = try!(git2::Repository::discover(new_path));
+ let repo = try!(git2::Repository::discover(path));
let workdir = match repo.workdir() {
- Some(w) => Path::new(w.as_os_str().as_bytes()),
+ Some(w) => w,
None => return Ok(Git { statuses: vec![] }), // bare repo
};
let statuses = try!(repo.statuses(None)).iter()
- .map(|e| (workdir.join(e.path_bytes()), e.status()))
+ .map(|e| (workdir.join(Path::new(e.path().unwrap())), e.status()))
.collect();
+
Ok(Git { statuses: statuses })
}
/// Get the status for the file at the given path, if present.
pub fn status(&self, path: &Path) -> String {
let status = self.statuses.iter()
- .find(|p| &p.0 == path);
+ .find(|p| p.0.as_path() == path);
match status {
Some(&(_, s)) => ANSIStrings( &[Git::index_status(s), Git::working_tree_status(s) ]).to_string(),
None => GREY.paint("--").to_string(),
@@ -52,7 +44,7 @@ impl Git {
/// directories, which don't really have an 'official' status.
pub fn dir_status(&self, dir: &Path) -> String {
let s = self.statuses.iter()
- .filter(|p| dir.is_ancestor_of(&p.0))
+ .filter(|p| p.0.starts_with(dir))
.fold(git2::Status::empty(), |a, b| a | b.1);
ANSIStrings( &[Git::index_status(s), Git::working_tree_status(s)] ).to_string()
@@ -83,3 +75,4 @@ impl Git {
}
}
}
+
diff --git a/src/feature/xattr_darwin.rs b/src/feature/xattr_darwin.rs
index d3f3428..fc682c9 100644
--- a/src/feature/xattr_darwin.rs
+++ b/src/feature/xattr_darwin.rs
@@ -1,14 +1,13 @@
//! Extended attribute support for darwin
extern crate libc;
-use std::ffi::CString;
+use std::io;
+use std::path::Path;
use std::ptr;
use std::mem;
-use std::old_io as io;
-use std::old_path::GenericPath;
-use std::old_path::posix::Path;
use self::libc::{c_int, size_t, ssize_t, c_char, c_void, uint32_t};
+
/// Don't follow symbolic links
const XATTR_NOFOLLOW: c_int = 0x0001;
/// Expose HFS Compression extended attributes
@@ -41,15 +40,21 @@ pub struct Attribute {
impl Attribute {
/// Lists the extended attribute of `path`.
/// Does follow symlinks by default.
- pub fn list_attrs(path: &Path, flags: &[ListFlags]) -> io::IoResult<Vec<Attribute>> {
+ pub fn list_attrs(path: &Path, flags: &[ListFlags]) -> io::Result<Vec<Attribute>> {
let mut c_flags: c_int = 0;
for &flag in flags.iter() {
c_flags |= flag as c_int
}
- let c_path = try!(CString::new(path.as_vec()));
+
+ let c_path = match path.as_os_str().to_cstring() {
+ Some(cstring) => cstring,
+ None => return Err(io::Error::new(io::ErrorKind::Other, "could not read extended attributes")),
+ };
+
let bufsize = unsafe {
listxattr(c_path.as_ptr(), ptr::null_mut(), 0, c_flags)
};
+
if bufsize > 0 {
let mut buf = vec![0u8; bufsize as usize];
let err = unsafe { listxattr(
@@ -88,18 +93,10 @@ impl Attribute {
}
Ok(names)
} else {
- Err(io::IoError {
- kind: io::OtherIoError,
- desc: "could not read extended attributes",
- detail: None
- })
+ Err(io::Error::new(io::ErrorKind::Other, "could not read extended attributes"))
}
} else {
- Err(io::IoError {
- kind: io::OtherIoError,
- desc: "could not read extended attributes",
- detail: None
- })
+ Err(io::Error::new(io::ErrorKind::Other, "could not read extended attributes"))
}
}
@@ -115,12 +112,12 @@ impl Attribute {
/// Lists the extended attributes.
/// Follows symlinks like `stat`
- pub fn list(path: &Path) -> io::IoResult<Vec<Attribute>> {
+ pub fn list(path: &Path) -> io::Result<Vec<Attribute>> {
Attribute::list_attrs(path, &[])
}
/// Lists the extended attributes.
/// Does not follow symlinks like `lstat`
- pub fn llist(path: &Path) -> io::IoResult<Vec<Attribute>> {
+ pub fn llist(path: &Path) -> io::Result<Vec<Attribute>> {
Attribute::list_attrs(path, &[ListFlags::NoFollow])
}
diff --git a/src/feature/xattr_linux.rs b/src/feature/xattr_linux.rs
index 06496ea..9d45345 100644
--- a/src/feature/xattr_linux.rs
+++ b/src/feature/xattr_linux.rs
@@ -2,10 +2,9 @@
extern crate libc;
use std::ffi::CString;
+use std::io;
+use std::path::Path;
use std::ptr;
-use std::old_io as io;
-use std::old_path::GenericPath;
-use std::old_path::posix::Path;
use self::libc::{size_t, ssize_t, c_char, c_void};
extern "C" {
@@ -36,15 +35,21 @@ pub struct Attribute {
impl Attribute {
/// Lists the extended attribute of `path`.
/// Does follow symlinks by default.
- pub fn list_attrs(path: &Path, do_follow: FollowSymlinks) -> io::IoResult<Vec<Attribute>> {
+ pub fn list_attrs(path: &Path, do_follow: FollowSymlinks) -> io::Result<Vec<Attribute>> {
let (listxattr, getxattr) = match do_follow {
FollowSymlinks::Yes => (listxattr, getxattr),
FollowSymlinks::No => (llistxattr, lgetxattr),
};
- let c_path = try!(CString::new(path.as_vec()));
+
+ let c_path = match path.as_os_str().to_cstring() {
+ Some(cstring) => cstring,
+ None => return Err(io::Error::new(io::ErrorKind::Other, "could not read extended attributes")),
+ };
+
let bufsize = unsafe {
listxattr(c_path.as_ptr(), ptr::null_mut(), 0)
};
+
if bufsize > 0 {
let mut buf = vec![0u8; bufsize as usize];
let err = unsafe { listxattr(
@@ -79,18 +84,10 @@ impl Attribute {
}
Ok(names)
} else {
- Err(io::IoError {
- kind: io::OtherIoError,
- desc: "could not read extended attributes",
- detail: None
- })
+ Err(io::Error::new(io::ErrorKind::Other, "could not read extended attributes"))
}
} else {
- Err(io::IoError {
- kind: io::OtherIoError,
- desc: "could not read extended attributes",
- detail: None
- })
+ Err(io::Error::new(io::ErrorKind::Other, "could not read extended attributes"))
}
}
@@ -106,12 +103,12 @@ impl Attribute {
/// Lists the extended attributes.
/// Follows symlinks like `stat`
- pub fn list(path: &Path) -> io::IoResult<Vec<Attribute>> {
+ pub fn list(path: &Path) -> io::Result<Vec<Attribute>> {
Attribute::list_attrs(path, FollowSymlinks::Yes)
}
/// Lists the extended attributes.
/// Does not follow symlinks like `lstat`
- pub fn llist(path: &Path) -> io::IoResult<Vec<Attribute>> {
+ pub fn llist(path: &Path) -> io::Result<Vec<Attribute>> {
Attribute::list_attrs(path, FollowSymlinks::No)
}