Просмотр исходного кода

fix: dereferencing links groups.

Signed-off-by: Christina Sørensen <christina@cafkafk.com>
Andrzej Grzeslak 3 лет назад
Родитель
Сommit
64948b8d09
5 измененных файлов с 31 добавлено и 15 удалено
  1. 8 2
      src/fs/file.rs
  2. 20 11
      src/output/render/groups.rs
  3. 1 1
      src/output/render/mod.rs
  4. 1 1
      src/output/table.rs
  5. 1 0
      src/theme/mod.rs

+ 8 - 2
src/fs/file.rs

@@ -338,8 +338,14 @@ impl<'dir> File<'dir> {
     }
 
     /// The ID of the group that owns this file.
-    pub fn group(&self) -> f::Group {
-        f::Group(self.metadata.gid())
+    pub fn group(&self) -> Option<f::Group> {
+        if self.is_link() && self.deref_links {
+            match self.link_target_recurse() {
+               FileTarget::Ok(f) => return f.group(),
+               _ => return None,
+            }
+        }
+        Some(f::Group(self.metadata.gid()))
     }
 
     /// This file’s size, if it’s a regular file.

+ 20 - 11
src/output/render/groups.rs

@@ -5,18 +5,25 @@ use crate::fs::fields as f;
 use crate::output::cell::TextCell;
 use crate::output::table::UserFormat;
 
+pub trait Render{
+    fn render<C: Colours, U: Users+Groups>(self, colours: &C, users: &U, format: UserFormat) -> TextCell;
+}
 
-impl f::Group {
-    pub fn render<C: Colours, U: Users+Groups>(self, colours: &C, users: &U, format: UserFormat) -> TextCell {
+impl Render for Option<f::Group> {
+    fn render<C: Colours, U: Users+Groups>(self, colours: &C, users: &U, format: UserFormat) -> TextCell {
         use users::os::unix::GroupExt;
 
         let mut style = colours.not_yours();
 
-        let group = match users.get_group_by_gid(self.0) {
-            Some(g)  => (*g).clone(),
-            None     => return TextCell::paint(style, self.0.to_string()),
+        let group = match self {
+            Some(g) => match users.get_group_by_gid(g.0) {
+                Some(g) => (*g).clone(),
+                None    => return TextCell::paint(style, g.0.to_string()),
+            },
+            None => return TextCell::blank(colours.no_group()),
         };
 
+
         let current_uid = users.get_current_uid();
         if let Some(current_user) = users.get_user_by_uid(current_uid) {
 
@@ -40,13 +47,14 @@ impl f::Group {
 pub trait Colours {
     fn yours(&self) -> Style;
     fn not_yours(&self) -> Style;
+    fn no_group(&self) -> Style;
 }
 
 
 #[cfg(test)]
 #[allow(unused_results)]
 pub mod test {
-    use super::Colours;
+    use super::{Colours, Render};
     use crate::fs::fields as f;
     use crate::output::cell::TextCell;
     use crate::output::table::UserFormat;
@@ -63,6 +71,7 @@ pub mod test {
     impl Colours for TestColours {
         fn yours(&self)     -> Style { Fixed(80).normal() }
         fn not_yours(&self) -> Style { Fixed(81).normal() }
+        fn no_group(&self)   -> Style { Black.italic() }
     }
 
 
@@ -71,7 +80,7 @@ pub mod test {
         let mut users = MockUsers::with_current_uid(1000);
         users.add_group(Group::new(100, "folk"));
 
-        let group = f::Group(100);
+        let group = Some(f::Group(100));
         let expected = TextCell::paint_str(Fixed(81).normal(), "folk");
         assert_eq!(expected, group.render(&TestColours, &users, UserFormat::Name));
 
@@ -84,7 +93,7 @@ pub mod test {
     fn unnamed() {
         let users = MockUsers::with_current_uid(1000);
 
-        let group = f::Group(100);
+        let group = Some(f::Group(100));
         let expected = TextCell::paint_str(Fixed(81).normal(), "100");
         assert_eq!(expected, group.render(&TestColours, &users, UserFormat::Name));
         assert_eq!(expected, group.render(&TestColours, &users, UserFormat::Numeric));
@@ -96,7 +105,7 @@ pub mod test {
         users.add_user(User::new(2, "eve", 100));
         users.add_group(Group::new(100, "folk"));
 
-        let group = f::Group(100);
+        let group = Some(f::Group(100));
         let expected = TextCell::paint_str(Fixed(80).normal(), "folk");
         assert_eq!(expected, group.render(&TestColours, &users, UserFormat::Name))
     }
@@ -109,14 +118,14 @@ pub mod test {
         let test_group = Group::new(100, "folk").add_member("eve");
         users.add_group(test_group);
 
-        let group = f::Group(100);
+        let group = Some(f::Group(100));
         let expected = TextCell::paint_str(Fixed(80).normal(), "folk");
         assert_eq!(expected, group.render(&TestColours, &users, UserFormat::Name))
     }
 
     #[test]
     fn overflow() {
-        let group = f::Group(2_147_483_648);
+        let group = Some(f::Group(2_147_483_648));
         let expected = TextCell::paint_str(Fixed(81).normal(), "2147483648");
         assert_eq!(expected, group.render(&TestColours, &MockUsers::with_current_uid(0), UserFormat::Numeric));
     }

+ 1 - 1
src/output/render/mod.rs

@@ -8,7 +8,7 @@ mod git;
 pub use self::git::Colours as GitColours;
 
 mod groups;
-pub use self::groups::Colours as GroupColours;
+pub use self::groups::{Colours as GroupColours, Render as GroupRender};
 
 mod inode;
 // inode uses just one colour

+ 1 - 1
src/output/table.rs

@@ -13,7 +13,7 @@ use users::UsersCache;
 use crate::fs::{File, fields as f};
 use crate::fs::feature::git::GitCache;
 use crate::output::cell::TextCell;
-use crate::output::render::{TimeRender, UserRender};
+use crate::output::render::{GroupRender, TimeRender, UserRender};
 use crate::output::time::TimeFormat;
 use crate::theme::Theme;
 

+ 1 - 0
src/theme/mod.rs

@@ -232,6 +232,7 @@ impl render::GitColours for Theme {
 impl render::GroupColours for Theme {
     fn yours(&self)      -> Style { self.ui.users.group_yours }
     fn not_yours(&self)  -> Style { self.ui.users.group_not_yours }
+    fn no_group(&self)   -> Style { self.ui.punctuation }
 }
 
 impl render::LinksColours for Theme {