Skip to content

Commit

Permalink
Merge #130
Browse files Browse the repository at this point in the history
130: Implement ls r=GrayJack a=jeremyvii

This PR implements the `ls` utility. Below lists the arguments with the short and long flags.

- [x] `-A`|`--almost-all`
- [x] `-C`|`--order-top-to-bottom`
- [x] `-F`|`--classify`
- [x] `-H`|`--no-dereference`
- [x] `-L`|`--dereference`
- [x] `-R`|`--recursive`
- [x] `-S`|`--sort-size`
- [x] `-a`|`--all`
- [x] `-c`|`--file-status-modification`
- [x] `-d`|`--directory`
- [x] `-f`|`--no-sort`
- [x] `-g`|`--no-owner`
- [x] `-i`|`--inode`
- [x] `-k`|`--block-size`
- [x] `-l`|`--list`
- [x] `-m`|`--comma-separate`
- [x] `-n`|`--numeric-uid-gid`
- [x] `-o`|`--no-group`
- [x] `-p`|`--indicator`
- [x] `-q`|`--hide-control-chars`
- [x] `-r`|`--reverse`
- [x] `-s`|`--size`
- [x] `-t`|`--time`
- [x] `-u`|`--last-accessed`
- [x] `-x`|`--order-left-to-write`
- [x] `-1`|`--one-per-line`

Co-authored-by: Jeremy Jackson <git@jeremyvii.com>
  • Loading branch information
bors[bot] and jeremyvii authored Dec 28, 2020
2 parents 8e8efec + 9ffb259 commit 8df4130
Show file tree
Hide file tree
Showing 21 changed files with 1,308 additions and 2 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ members = [
"id",
"link",
"logname",
"ls",
"mkdir",
"mkfifo",
"mktemp",
Expand Down
1 change: 1 addition & 0 deletions DragonflyBSD.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ members = [
"groups",
"head",
"id",
'ls',
"link",
"logname",
"mkdir",
Expand Down
1 change: 1 addition & 0 deletions FreeBSD.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ members = [
"groups",
"head",
"id",
'ls',
"link",
"logname",
"mkdir",
Expand Down
1 change: 1 addition & 0 deletions Fuchsia.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ members = [
"groups",
"head",
"id",
'ls',
"link",
"logname",
"mkdir",
Expand Down
1 change: 1 addition & 0 deletions Haiku.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ members = [
"groups",
"head",
"id",
'ls',
"link",
"logname",
"mkdir",
Expand Down
1 change: 1 addition & 0 deletions Linux.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ members = [
"head",
"id",
"link",
'ls',
"logname",
"mkdir",
"mkfifo",
Expand Down
1 change: 1 addition & 0 deletions MacOS.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ members = [
"groups",
"head",
"id",
'ls',
"link",
"logname",
"mkdir",
Expand Down
1 change: 1 addition & 0 deletions NetBSD.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ members = [
"groups",
"head",
"id",
'ls',
"link",
"logname",
"mkdir",
Expand Down
1 change: 1 addition & 0 deletions OpenBSD.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ members = [
"groups",
"head",
"id",
'ls',
"link",
"logname",
"mkdir",
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ cargo install --path .
| link | | | X |
| ln | X | | |
| logname | | | X |
| ls | X | | |
| ls | | X | |
| mkdir | | | X |
| mktemp | | | X |
| mkfifo | X | | |
Expand Down
1 change: 1 addition & 0 deletions Solaris.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ members = [
"groups",
"head",
"id",
'ls',
"link",
"logname",
"mkdir",
Expand Down
1 change: 1 addition & 0 deletions Unix.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ members = [
"groups",
"head",
"id",
'ls',
"link",
"logname",
"mkdir",
Expand Down
29 changes: 28 additions & 1 deletion coreutils_core/src/os/tty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use std::{
os::unix::io::AsRawFd,
};

use libc::ttyname;
use libc::{ioctl, ttyname, winsize, TIOCGWINSZ};

// use crate::file_descriptor::FileDescriptor;

Expand Down Expand Up @@ -99,3 +99,30 @@ impl<T: AsRawFd> IsTTY for T {
pub fn is_tty(file_descriptor: &impl AsRawFd) -> bool {
unsafe { libc::isatty(file_descriptor.as_raw_fd()) == 1 }
}

/// Gets the width and height of a TTY.
///
/// ## Example
/// ``` rust
/// use coreutils_core::os::tty::tty_dimensions;
/// let dimensions = tty_dimensions(&std::io::stdout());
/// ```
#[inline]
pub fn tty_dimensions(file_descriptor: &impl AsRawFd) -> Option<(u16, u16)> {
if !is_tty(file_descriptor) {
return None;
}

let mut size = winsize { ws_row: 0, ws_col: 0, ws_xpixel: 0, ws_ypixel: 0 };

let tiocgwinsz = TIOCGWINSZ;

#[cfg(target_os = "freebsd")]
let tiocgwinsz: u64 = tiocgwinsz.into();

if unsafe { ioctl(file_descriptor.as_raw_fd(), tiocgwinsz, &mut size) } == -1 {
return None;
}

Some((size.ws_col, size.ws_row))
}
21 changes: 21 additions & 0 deletions ls/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
[package]
name = "ls"
version = "0.1.0"
authors = ["Jeremy Jackson <git@jeremyvii.com>"]
license = "MPL-2.0-no-copyleft-exception"
build = "build.rs"
edition = "2018"
description = "List information about the FILEs (the current directory by default)."

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
clap = { version = "^2.33.0", features = ["wrap_help"] }
coreutils_core = { path = "../coreutils_core" }
unix_mode = "0.1.1"
chrono = "0.4"
ansi_term = "0.12.1"
term_grid = "0.2.0"

[build-dependencies]
clap = "^2.33.0"
24 changes: 24 additions & 0 deletions ls/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
use std::env;

use clap::Shell;

#[path = "src/cli.rs"]
mod cli;

fn main() {
let mut app = cli::create_app();

let out_dir = match env::var("OUT_DIR") {
Ok(dir) => dir,
Err(err) => {
eprintln!("No OUT_DIR: {}", err);
return;
},
};

app.gen_completions("ls", Shell::Zsh, out_dir.clone());
app.gen_completions("ls", Shell::Fish, out_dir.clone());
app.gen_completions("ls", Shell::Bash, out_dir.clone());
app.gen_completions("ls", Shell::PowerShell, out_dir.clone());
app.gen_completions("ls", Shell::Elvish, out_dir);
}
197 changes: 197 additions & 0 deletions ls/src/cli.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
use clap::{
crate_authors, crate_description, crate_name, crate_version, App, AppSettings::ColoredHelp, Arg,
};

pub(crate) fn create_app<'a, 'b>() -> App<'a, 'b> {
App::new(crate_name!())
.version(crate_version!())
.author(crate_authors!())
.about(crate_description!())
.help_message("Display help information.")
.version_message("Display version information.")
.help_short("?")
.settings(&[ColoredHelp])
.arg(
Arg::with_name("FILE")
.help("File(s) to list")
.required(true)
.multiple(true)
.default_value("."),
)
.arg(
Arg::with_name("all")
.help(
"Write out all directory entries, including those whose names begin with a \
<period> ( '.' ).",
)
.short("a")
.long("all"),
)
.arg(
Arg::with_name("almost_all")
.help(
"Write out all directory entries, including those whose names begin with a \
<period> ( '.' ) but excluding the entries dot and dot-dot (if they exist).",
)
.short("A")
.long("almost-all"),
)
.arg(
Arg::with_name("file_status_modification")
.help(
"Use time of last modification of the file status information instead of last \
modification of the file itself for sorting -t or writing -l.",
)
.short("c")
.long("file-status-modification"),
)
.arg(
Arg::with_name("order_top_to_bottom")
.help("Write multi-text-column output with entries sorted down the columns.")
.short("C")
.long("order-top-to-bottom"),
)
.arg(
Arg::with_name("directory")
.help("List directories and files themselves, rather than their contents.")
.short("d")
.long("directory"),
)
.arg(
Arg::with_name("no_sort")
.help(
"Output is not sorted. This option turns on -a. It also negates the effect of \
the -r, -S and -t options.",
)
.short("f")
.long("no-sort"),
)
.arg(
Arg::with_name("classify")
.help("Append indicator (one of */=>@|) to entries.")
.short("F")
.long("classify"),
)
.arg(
Arg::with_name("no_dereference")
.help("Follow symbolic links listed on the command line.")
.short("H")
.long("no-dereference"),
)
.arg(
Arg::with_name("block_size")
.help(
"Set the block size for the -s option and the per-directory block count \
written for the -l, -n, -s, -g, and -o options to 1024 bytes.",
)
.short("k")
.long("block-size"),
)
.arg(
Arg::with_name("comma_separate")
.help("Fill width with a comma separated list of entries.")
.short("m")
.long("comma-separate"),
)
.arg(
Arg::with_name("dereference")
.help(
"When showing file information for a symbolic link, show information for the \
file the link references rather than for the link itself.",
)
.short("L")
.long("dereference"),
)
.arg(
Arg::with_name("indicator")
.help("Write a <slash> ( '/' ) after each filename if that file is a directory.")
.short("p")
.long("indicator"),
)
.arg(
Arg::with_name("inode")
.help("For each file, write the file's file serial number.")
.short("i")
.long("inode"),
)
.arg(
Arg::with_name("last_accessed")
.help(
"Use time of last access instead of last modification of the file for sorting \
-t or writing -l.",
)
.short("u")
.long("last-accessed"),
)
.arg(Arg::with_name("list").help("Use a long listing format").short("l").long("list"))
.arg(
Arg::with_name("no_owner")
.help("Like -l, but do not list owner.")
.short("g")
.long("no-owner"),
)
.arg(
Arg::with_name("numeric_uid_gid")
.help("Like -l, but list numeric user and group IDs.")
.short("n")
.long("numeric-uid-gid"),
)
.arg(
Arg::with_name("no_group")
.help("Like -l, but do not list group.")
.short("o")
.long("no-group"),
)
.arg(
Arg::with_name("hide_control_chars")
.help(
"Force each instance of non-printable filename characters to be written as \
the � character. This is the default behavior if the output is to a terminal \
device.",
)
.short("q")
.long("hide-control-chars"),
)
.arg(
Arg::with_name("reverse")
.help("Reverse order while sorting.")
.short("r")
.long("reverse"),
)
.arg(
Arg::with_name("recursive")
.help("Recursively print subdirectories.")
.short("R")
.long("recursive"),
)
.arg(
Arg::with_name("size")
.help("Print the allocated size of each file, in blocks.")
.short("s")
.long("size"),
)
.arg(
Arg::with_name("sort_size")
.help("Sort by first file size, largest first.")
.short("S")
.long("sort-size"),
)
.arg(
Arg::with_name("time")
.help("Sort by modification time, newest first.")
.short("t")
.long("time"),
)
.arg(
Arg::with_name("order_left_to_right")
.help("Sort columns left to right.")
.short("x")
.long("order-left-to-right"),
)
.arg(
Arg::with_name("one_per_line")
.help("Force output to be one entry per line.")
.short("1")
.long("one-per-line"),
)
}
Loading

0 comments on commit 8df4130

Please sign in to comment.