ソースを参照

Merge branch 'main' into fix-zsh-completions

MartinFillon 2 年 前
コミット
c889fe41a5
10 ファイル変更253 行追加87 行削除
  1. 26 0
      CHANGELOG.md
  2. 1 8
      Cargo.lock
  3. 1 2
      Cargo.toml
  4. 73 1
      Justfile
  5. 24 15
      src/output/grid.rs
  6. 19 9
      src/output/grid_details.rs
  7. 2 0
      src/output/icons.rs
  8. 91 33
      src/output/render/groups.rs
  9. 3 4
      src/output/table.rs
  10. 13 15
      src/output/time.rs

+ 26 - 0
CHANGELOG.md

@@ -1,5 +1,27 @@
 # Changelog
 
+## [0.15.2] - 2023-11-02
+
+### Bug Fixes
+
+- Correct width when --no-quotes is used
+- Clippy lint and add option to grid-details
+- --smart-group only works for current user
+
+### Features
+
+- Add Typst to the recognized files
+
+### Refactor
+
+- Replace `lazy_static` with `once_cell`
+- Replace plain values with TextColours
+
+### Testing
+
+- Added more content to the dir generator
+- Changed size of one of the files
+
 ## [0.15.1] - 2023-10-26
 
 ### Bug Fixes
@@ -24,6 +46,10 @@
 
 - Support for displaying blocksize on directories
 
+### Miscellaneous Tasks
+
+- Release eza v0.15.1
+
 ### Refactor
 
 - Move total-size calculations to File

+ 1 - 8
Cargo.lock

@@ -356,14 +356,13 @@ dependencies = [
 
 [[package]]
 name = "eza"
-version = "0.15.1"
+version = "0.15.2"
 dependencies = [
  "ansiterm",
  "chrono",
  "criterion",
  "git2",
  "glob",
- "lazy_static",
  "libc",
  "locale",
  "log",
@@ -555,12 +554,6 @@ dependencies = [
  "wasm-bindgen",
 ]
 
-[[package]]
-name = "lazy_static"
-version = "1.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
-
 [[package]]
 name = "libc"
 version = "0.2.149"

+ 1 - 2
Cargo.toml

@@ -16,7 +16,7 @@ readme = "README.md"
 homepage = "https://github.com/eza-community/eza"
 license = "MIT"
 repository = "https://github.com/eza-community/eza"
-version = "0.15.1"
+version = "0.15.2"
 
 
 [package.metadata.deb]
@@ -74,7 +74,6 @@ name = "eza"
 ansiterm = "0.12.2"
 chrono = { version = "0.4.31", default-features = false, features = ["clock"] }
 glob = "0.3"
-lazy_static = "1.3"
 libc = "0.2"
 locale = "0.2"
 log = "0.4"

+ 73 - 1
Justfile

@@ -212,10 +212,12 @@ test_dir := "tests/test_dir"
 
 gen_test_dir:
     #!/usr/bin/env bash
-    rm {{test_dir}} -r;
+    rm {{test_dir}} -rf;
     mkdir -p {{test_dir}}
     cd {{test_dir}};
 
+    sudo groupadd -f eza_test
+
     # BEGIN grid
     mkdir -p grid
     cd grid
@@ -266,6 +268,76 @@ gen_test_dir:
 
     # END test_root
 
+    # BEGIN test_symlinks
+
+    mkdir -p symlinks
+    touch symlinks/file --date=@0
+    ln -s file symlinks/symlink
+    ln -s symlink symlinks/symlink2
+    mkdir -p symlinks/dir
+    ln -s dir symlinks/symlink3
+    ln -s pipitek symlinks/symlink4
+
+    # END test_symlinks
+
+    # BEGIN test_perms
+
+    mkdir -p perms
+    touch perms/file --date=@0
+    touch perms/file2 --date=@0
+    chmod 777 perms/file
+    chmod 001 perms/file2
+
+    # END test_perms
+
+    # BEGIN test_group
+    mkdir -p group
+    touch group/file --date=@0
+    sudo chgrp eza_test group/file
+    # END test_group
+
+    # BEGIN test_size
+    mkdir -p size
+    touch size/1M --date=@0
+    dd if=/dev/zero of=size/1M bs=1 count=0 seek=1M
+    touch size/1K --date=@0
+    dd if=/dev/zero of=size/1K bs=1 count=0 seek=1K
+    touch size/1B --date=@0
+    dd if=/dev/zero of=size/1B bs=1 count=0 seek=1
+    touch size/1337 --date=@0
+    dd if=/dev/zero of=size/1337 bs=1 count=0 seek=1337
+    # END test_size
+    
+    # BEGIN test_time
+    mkdir -p time
+    touch time/epoch --date=@0
+    touch time/1s --date=@1
+    touch time/1m --date=@60
+    touch time/1h --date=@3600
+    touch time/1d --date=@86400
+    touch time/1y --date=@31536000
+    # END test_time
+
+    # BEGIN test_icons
+    mkdir -p icons
+    touch icons/file --date=@0
+    touch icons/go.go --date=@0
+    touch icons/rust.rs --date=@0
+    touch icons/c.c --date=@0
+    touch icons/c++.cpp --date=@0
+    touch icons/python.py --date=@0
+    touch icons/java.java --date=@0
+    touch icons/javascript.js --date=@0
+    touch icons/html.html --date=@0
+    touch icons/css.css --date=@0
+    touch icons/php.php --date=@0
+    touch icons/ruby.rb --date=@0
+    touch icons/shell.sh --date=@0
+    touch icons/unknown.unknown --date=@0
+    touch icons/man.1 --date=@0
+    touch icons/marked.md --date=@0
+    # END test_icons
+
     eza -l --grid;
 
 # Runs integration tests in nix sandbox

+ 24 - 15
src/output/grid.rs

@@ -8,6 +8,8 @@ use crate::output::file_name::{Classify, Options as FileStyle};
 use crate::output::file_name::{EmbedHyperlinks, ShowIcons};
 use crate::theme::Theme;
 
+use super::file_name::QuoteStyle;
+
 #[derive(PartialEq, Eq, Debug, Copy, Clone)]
 pub struct Options {
     pub across: bool,
@@ -55,27 +57,34 @@ impl<'a> Render<'a> {
                 } else {
                     0
                 };
-
-            let space_filename_offset = if file.name.contains(' ') || file.name.contains('\'') {
-                2
-            } else {
-                0
+            let space_filename_offset = match self.file_style.quote_style {
+                QuoteStyle::QuoteSpaces if file.name.contains(' ') => 2,
+                QuoteStyle::NoQuotes => 0,
+                QuoteStyle::QuoteSpaces => 0, // Default case
             };
-
             let contents = filename.paint();
-            #[rustfmt::skip]
             let width = match (
                 filename.options.embed_hyperlinks,
                 filename.options.show_icons,
             ) {
-                ( EmbedHyperlinks::On, ShowIcons::Always(spacing) | ShowIcons::Automatic(spacing) )
-                    => filename.bare_width() + classification_width + 1 + (spacing as usize) + space_filename_offset,
-                ( EmbedHyperlinks::On, ShowIcons::Never )
-                    => filename.bare_width() + classification_width + space_filename_offset,
-                ( EmbedHyperlinks::Off, ShowIcons::Always(spacing) | ShowIcons::Automatic(spacing) )
-                    => filename.bare_width() + 1 + (spacing as usize) + space_filename_offset,
-                ( EmbedHyperlinks::Off, _ )
-                    => *contents.width(),
+                (
+                    EmbedHyperlinks::On,
+                    ShowIcons::Always(spacing) | ShowIcons::Automatic(spacing),
+                ) => {
+                    filename.bare_width()
+                        + classification_width
+                        + 1
+                        + (spacing as usize)
+                        + space_filename_offset
+                }
+                (EmbedHyperlinks::On, ShowIcons::Never) => {
+                    filename.bare_width() + classification_width + space_filename_offset
+                }
+                (
+                    EmbedHyperlinks::Off,
+                    ShowIcons::Always(spacing) | ShowIcons::Automatic(spacing),
+                ) => filename.bare_width() + 1 + (spacing as usize) + space_filename_offset,
+                (EmbedHyperlinks::Off, _) => *contents.width(),
             };
 
             grid.add(tg::Cell {

+ 19 - 9
src/output/grid_details.rs

@@ -19,6 +19,8 @@ use crate::output::table::{Options as TableOptions, Row as TableRow, Table};
 use crate::output::tree::{TreeDepth, TreeParams};
 use crate::theme::Theme;
 
+use super::file_name::QuoteStyle;
+
 #[derive(PartialEq, Eq, Debug)]
 pub struct Options {
     pub grid: GridOptions,
@@ -162,16 +164,24 @@ impl<'a> Render<'a> {
             .map(|file| {
                 let filename = self.file_style.for_file(file, self.theme);
                 let contents = filename.paint();
-                let space_filename_offset = if file.name.contains(' ') || file.name.contains('\'') {
-                    2
-                } else {
-                    0
+                let space_filename_offset = match self.file_style.quote_style {
+                    QuoteStyle::QuoteSpaces if file.name.contains(' ') => 2,
+                    QuoteStyle::NoQuotes => 0,
+                    QuoteStyle::QuoteSpaces => 0, // Default case
                 };
-                #[rustfmt::skip]
-                let width = match (filename.options.embed_hyperlinks, filename.options.show_icons) {
-                    (EmbedHyperlinks::On, ShowIcons::Automatic(spacing)) => filename.bare_width() + 1 + (spacing as usize) + space_filename_offset,
-                    (EmbedHyperlinks::On, ShowIcons::Always(spacing)) => filename.bare_width() + 1 + (spacing as usize) + space_filename_offset,
-                    (EmbedHyperlinks::On, ShowIcons::Never) => filename.bare_width() + space_filename_offset,
+                let width = match (
+                    filename.options.embed_hyperlinks,
+                    filename.options.show_icons,
+                ) {
+                    (EmbedHyperlinks::On, ShowIcons::Automatic(spacing)) => {
+                        filename.bare_width() + 1 + (spacing as usize) + space_filename_offset
+                    }
+                    (EmbedHyperlinks::On, ShowIcons::Always(spacing)) => {
+                        filename.bare_width() + 1 + (spacing as usize) + space_filename_offset
+                    }
+                    (EmbedHyperlinks::On, ShowIcons::Never) => {
+                        filename.bare_width() + space_filename_offset
+                    }
                     (EmbedHyperlinks::Off, _) => *contents.width(),
                 };
 

+ 2 - 0
src/output/icons.rs

@@ -103,6 +103,7 @@ impl Icons {
     const SUBTITLE: char        = '\u{f0a16}'; // 󰨖
     const TERRAFORM: char       = '\u{f1062}'; // 󱁢
     const TEXT: char            = '\u{f15c}';  // 
+    const TYPST: char           = '\u{1D42D}'; // 𝐭
     const UNITY: char           = '\u{e721}';  // 
     const VECTOR: char          = '\u{f0559}'; // 󰕙
     const VIDEO: char           = '\u{f03d}';  // 
@@ -702,6 +703,7 @@ const EXTENSION_ICONS: Map<&'static str, char> = phf_map! {
     "ttf"            => Icons::FONT,             // 
     "twig"           => '\u{e61c}',              // 
     "txt"            => Icons::TEXT,             // 
+    "typ"            => Icons::TYPST,            // 𝐭
     "txz"            => Icons::COMPRESSED,       // 
     "tz"             => Icons::COMPRESSED,       // 
     "tzo"            => Icons::COMPRESSED,       // 

+ 91 - 33
src/output/render/groups.rs

@@ -2,6 +2,7 @@ use ansiterm::Style;
 use uzers::{Groups, Users};
 
 use crate::fs::fields as f;
+use crate::fs::fields::User;
 use crate::output::cell::TextCell;
 use crate::output::table::{GroupFormat, UserFormat};
 
@@ -12,6 +13,7 @@ pub trait Render {
         users: &U,
         user_format: UserFormat,
         group_format: GroupFormat,
+        file_user: Option<User>,
     ) -> TextCell;
 }
 
@@ -22,6 +24,7 @@ impl Render for Option<f::Group> {
         users: &U,
         user_format: UserFormat,
         group_format: GroupFormat,
+        file_user: Option<User>,
     ) -> TextCell {
         use uzers::os::unix::GroupExt;
 
@@ -53,20 +56,15 @@ impl Render for Option<f::Group> {
             UserFormat::Numeric => group.gid().to_string(),
         };
 
-        group_name = match group_format {
-            GroupFormat::Smart => {
-                if let Some(current_user) = users.get_user_by_uid(current_uid) {
-                    if current_user.name() == group.name() {
-                        ":".to_string()
-                    } else {
-                        group_name
+        if let GroupFormat::Smart = group_format {
+            if let Some(file_uid) = file_user {
+                if let Some(file_user) = users.get_user_by_uid(file_uid.0) {
+                    if file_user.name().to_string_lossy() == group.name().to_string_lossy() {
+                        group_name = ":".to_string();
                     }
-                } else {
-                    group_name
                 }
             }
-            GroupFormat::Regular => group_name,
-        };
+        }
 
         TextCell::paint(style, group_name)
     }
@@ -109,20 +107,28 @@ pub mod test {
         users.add_group(Group::new(100, "folk"));
 
         let group = Some(f::Group(100));
-        let expected = TextCell::paint_str(Fixed(81).normal(), "folk");
+        let file_user = Some(f::User(1000));
+        let expected = TextCell::paint_str(TestColours.not_yours(), "folk");
         assert_eq!(
             expected,
-            group.render(&TestColours, &users, UserFormat::Name, GroupFormat::Regular)
+            group.render(
+                &TestColours,
+                &users,
+                UserFormat::Name,
+                GroupFormat::Regular,
+                file_user
+            )
         );
 
-        let expected = TextCell::paint_str(Fixed(81).normal(), "100");
+        let expected = TextCell::paint_str(TestColours.not_yours(), "100");
         assert_eq!(
             expected,
             group.render(
                 &TestColours,
                 &users,
                 UserFormat::Numeric,
-                GroupFormat::Regular
+                GroupFormat::Regular,
+                file_user
             )
         );
     }
@@ -132,10 +138,17 @@ pub mod test {
         let users = MockUsers::with_current_uid(1000);
 
         let group = Some(f::Group(100));
-        let expected = TextCell::paint_str(Fixed(81).normal(), "100");
+        let file_user = Some(f::User(1000));
+        let expected = TextCell::paint_str(TestColours.not_yours(), "100");
         assert_eq!(
             expected,
-            group.render(&TestColours, &users, UserFormat::Name, GroupFormat::Regular)
+            group.render(
+                &TestColours,
+                &users,
+                UserFormat::Name,
+                GroupFormat::Regular,
+                file_user
+            )
         );
         assert_eq!(
             expected,
@@ -143,7 +156,8 @@ pub mod test {
                 &TestColours,
                 &users,
                 UserFormat::Numeric,
-                GroupFormat::Regular
+                GroupFormat::Regular,
+                file_user
             )
         );
     }
@@ -155,10 +169,17 @@ pub mod test {
         users.add_group(Group::new(100, "folk"));
 
         let group = Some(f::Group(100));
-        let expected = TextCell::paint_str(Fixed(80).normal(), "folk");
+        let file_user = Some(f::User(2));
+        let expected = TextCell::paint_str(TestColours.yours(), "folk");
         assert_eq!(
             expected,
-            group.render(&TestColours, &users, UserFormat::Name, GroupFormat::Regular)
+            group.render(
+                &TestColours,
+                &users,
+                UserFormat::Name,
+                GroupFormat::Regular,
+                file_user
+            )
         )
     }
 
@@ -171,24 +192,33 @@ pub mod test {
         users.add_group(test_group);
 
         let group = Some(f::Group(100));
-        let expected = TextCell::paint_str(Fixed(80).normal(), "folk");
+        let file_user = Some(f::User(2));
+        let expected = TextCell::paint_str(TestColours.yours(), "folk");
         assert_eq!(
             expected,
-            group.render(&TestColours, &users, UserFormat::Name, GroupFormat::Regular)
+            group.render(
+                &TestColours,
+                &users,
+                UserFormat::Name,
+                GroupFormat::Regular,
+                file_user
+            )
         )
     }
 
     #[test]
     fn overflow() {
         let group = Some(f::Group(2_147_483_648));
-        let expected = TextCell::paint_str(Fixed(81).normal(), "2147483648");
+        let file_user = Some(f::User(1000));
+        let expected = TextCell::paint_str(TestColours.not_yours(), "2147483648");
         assert_eq!(
             expected,
             group.render(
                 &TestColours,
                 &MockUsers::with_current_uid(0),
                 UserFormat::Numeric,
-                GroupFormat::Regular
+                GroupFormat::Regular,
+                file_user
             )
         );
     }
@@ -196,33 +226,61 @@ pub mod test {
     #[test]
     fn smart() {
         let mut users = MockUsers::with_current_uid(1000);
-        users.add_user(User::new(1000, "user", 110));
+        users.add_user(User::new(1000, "user", 100));
+        users.add_user(User::new(1001, "http", 101));
         users.add_group(Group::new(100, "user"));
         users.add_group(Group::new(101, "http"));
 
-        let same_group = Some(f::Group(100));
-        let expected = TextCell::paint_str(Fixed(81).normal(), ":");
+        let user_group = Some(f::Group(100));
+        let user_file = Some(f::User(1000));
+        let expected = TextCell::paint_str(TestColours.yours(), ":");
         assert_eq!(
             expected,
-            same_group.render(&TestColours, &users, UserFormat::Name, GroupFormat::Smart)
+            user_group.render(
+                &TestColours,
+                &users,
+                UserFormat::Name,
+                GroupFormat::Smart,
+                user_file
+            )
         );
 
-        let expected = TextCell::paint_str(Fixed(81).normal(), ":");
+        let expected = TextCell::paint_str(TestColours.yours(), ":");
         assert_eq!(
             expected,
-            same_group.render(
+            user_group.render(
                 &TestColours,
                 &users,
                 UserFormat::Numeric,
-                GroupFormat::Smart
+                GroupFormat::Smart,
+                user_file
             )
         );
 
         let http_group = Some(f::Group(101));
-        let expected = TextCell::paint_str(Fixed(81).normal(), "http");
+        let expected = TextCell::paint_str(TestColours.not_yours(), "http");
         assert_eq!(
             expected,
-            http_group.render(&TestColours, &users, UserFormat::Name, GroupFormat::Smart)
+            http_group.render(
+                &TestColours,
+                &users,
+                UserFormat::Name,
+                GroupFormat::Smart,
+                user_file
+            )
+        );
+
+        let http_file = Some(f::User(1001));
+        let expected = TextCell::paint_str(TestColours.not_yours(), ":");
+        assert_eq!(
+            expected,
+            http_group.render(
+                &TestColours,
+                &users,
+                UserFormat::Name,
+                GroupFormat::Smart,
+                http_file
+            )
         );
     }
 }

+ 3 - 4
src/output/table.rs

@@ -5,8 +5,8 @@ use std::sync::{Mutex, MutexGuard};
 
 use chrono::prelude::*;
 
-use lazy_static::lazy_static;
 use log::*;
+use once_cell::sync::Lazy;
 #[cfg(unix)]
 use uzers::UsersCache;
 
@@ -352,9 +352,7 @@ impl Environment {
     }
 }
 
-lazy_static! {
-    static ref ENVIRONMENT: Environment = Environment::load_all();
-}
+static ENVIRONMENT: Lazy<Environment> = Lazy::new(Environment::load_all);
 
 pub struct Table<'a> {
     columns: Vec<Column>,
@@ -476,6 +474,7 @@ impl<'a> Table<'a> {
                 &*self.env.lock_users(),
                 self.user_format,
                 self.group_format,
+                file.user(),
             ),
             #[cfg(unix)]
             Column::SecurityContext => file.security_context().render(self.theme),

+ 13 - 15
src/output/time.rs

@@ -2,7 +2,7 @@
 
 use chrono::prelude::*;
 use core::cmp::max;
-use lazy_static::lazy_static;
+use once_cell::sync::Lazy;
 use std::time::Duration;
 use unicode_width::UnicodeWidthStr;
 
@@ -119,22 +119,20 @@ fn custom(time: &DateTime<FixedOffset>, fmt: &str) -> String {
     time.format(fmt).to_string()
 }
 
-lazy_static! {
+static CURRENT_YEAR: Lazy<i32> = Lazy::new(|| Local::now().year());
 
-    static ref CURRENT_YEAR: i32 = Local::now().year();
+static LOCALE: Lazy<locale::Time> =
+    Lazy::new(|| locale::Time::load_user_locale().unwrap_or_else(|_| locale::Time::english()));
 
-    static ref LOCALE: locale::Time = {
-        locale::Time::load_user_locale()
-               .unwrap_or_else(|_| locale::Time::english())
-    };
-
-    static ref MAX_MONTH_WIDTH: usize = {
-        // Some locales use a three-character wide month name (Jan to Dec);
-        // others vary between three to four (1月 to 12月, juil.). We check each month width
-        // to detect the longest and set the output format accordingly.
-        (0..11).map(|i| UnicodeWidthStr::width(&*LOCALE.short_month_name(i))).max().unwrap()
-    };
-}
+static MAX_MONTH_WIDTH: Lazy<usize> = Lazy::new(|| {
+    // Some locales use a three-character wide month name (Jan to Dec);
+    // others vary between three to four (1月 to 12月, juil.). We check each month width
+    // to detect the longest and set the output format accordingly.
+    (0..11)
+        .map(|i| UnicodeWidthStr::width(&*LOCALE.short_month_name(i)))
+        .max()
+        .unwrap()
+});
 
 #[cfg(test)]
 mod test {