1
0
mirror of https://github.com/uutils/coreutils synced 2024-07-01 06:54:36 +00:00

Compare commits

...

4 Commits

Author SHA1 Message Date
sreehari prasad
09db85597b
Merge 43b51647bd into 69b603bfe7 2024-06-28 19:56:03 +05:30
mhead
43b51647bd ls: gnu color-clear-to-eol fix 2024-06-28 19:55:48 +05:30
Daniel Hofstetter
69b603bfe7
Merge pull request #6503 from CausingBrick/issue-6495
date: fix date get timezone error while set utc time (#6495)
2024-06-28 16:15:56 +02:00
MengshengWu
e4ec608781 date: fix date get timezone error while set utc time (#6495) 2024-06-28 22:01:00 +08:00
6 changed files with 118 additions and 30 deletions

View File

@ -227,11 +227,9 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
Box::new(iter)
}
DateSource::Human(relative_time) => {
// Get the current DateTime<FixedOffset> for things like "1 year ago"
let current_time = DateTime::<FixedOffset>::from(Local::now());
// double check the result is overflow or not of the current_time + relative_time
// Double check the result is overflow or not of the current_time + relative_time
// it may cause a panic of chrono::datetime::DateTime add
match current_time.checked_add_signed(relative_time) {
match now.checked_add_signed(relative_time) {
Some(date) => {
let iter = std::iter::once(Ok(date));
Box::new(iter)

View File

@ -28,7 +28,12 @@ impl<'a> StyleManager<'a> {
}
}
pub(crate) fn apply_style(&mut self, new_style: Option<&Style>, name: &str) -> String {
pub(crate) fn apply_style(
&mut self,
new_style: Option<&Style>,
name: &str,
wrap: bool,
) -> String {
let mut style_code = String::new();
let mut force_suffix_reset: bool = false;
@ -57,7 +62,20 @@ impl<'a> StyleManager<'a> {
force_suffix_reset = true;
}
format!("{}{}{}", style_code, name, self.reset(force_suffix_reset))
// we need this clear to eol code in some terminals, for instance if the
// text is in the last row of the terminal meaning the terminal need to
// scroll up in order to print new text in this situation if the clear
// to eol code is not present the background of the text would stretch
// till the end of line
let clear_to_eol = if wrap { "\x1b[K" } else { "" };
format!(
"{}{}{}{}",
style_code,
name,
self.reset(force_suffix_reset),
clear_to_eol
)
}
/// Resets the current style and returns the default ANSI reset code to
@ -110,20 +128,22 @@ impl<'a> StyleManager<'a> {
path: &PathData,
md_option: Option<&Metadata>,
name: &str,
wrap: bool,
) -> String {
let style = self
.colors
.style_for_path_with_metadata(&path.p_buf, md_option);
self.apply_style(style, name)
self.apply_style(style, name, wrap)
}
pub(crate) fn apply_style_based_on_dir_entry(
&mut self,
dir_entry: &DirEntry,
name: &str,
wrap: bool,
) -> String {
let style = self.colors.style_for(dir_entry);
self.apply_style(style, name)
self.apply_style(style, name, wrap)
}
}
@ -137,12 +157,13 @@ pub(crate) fn color_name(
style_manager: &mut StyleManager,
out: &mut BufWriter<Stdout>,
target_symlink: Option<&PathData>,
wrap: bool,
) -> String {
if !path.must_dereference {
// If we need to dereference (follow) a symlink, we will need to get the metadata
if let Some(de) = &path.de {
// There is a DirEntry, we don't need to get the metadata for the color
return style_manager.apply_style_based_on_dir_entry(de, name);
return style_manager.apply_style_based_on_dir_entry(de, name, wrap);
}
}
@ -152,11 +173,11 @@ pub(crate) fn color_name(
// should not exit with an err, if we are unable to obtain the target_metadata
let md_res = get_metadata_with_deref_opt(&target.p_buf, path.must_dereference);
let md = md_res.or(path.p_buf.symlink_metadata());
style_manager.apply_style_based_on_metadata(path, md.ok().as_ref(), name)
style_manager.apply_style_based_on_metadata(path, md.ok().as_ref(), name, wrap)
} else {
let md_option = path.get_metadata(out);
let symlink_metadata = path.p_buf.symlink_metadata().ok();
let md = md_option.or(symlink_metadata.as_ref());
style_manager.apply_style_based_on_metadata(path, md, name)
style_manager.apply_style_based_on_metadata(path, md, name, wrap)
}
}

View File

@ -929,19 +929,19 @@ impl Config {
let width = match options.get_one::<String>(options::WIDTH) {
Some(x) => parse_width(x)?,
None => match terminal_size::terminal_size() {
Some((width, _)) => width.0,
None => match std::env::var_os("COLUMNS") {
Some(columns) => match columns.to_str().and_then(|s| s.parse().ok()) {
Some(columns) => columns,
None => {
show_error!(
"ignoring invalid width in environment variable COLUMNS: {}",
columns.quote()
);
DEFAULT_TERM_WIDTH
}
},
None => match std::env::var_os("COLUMNS") {
Some(columns) => match columns.to_str().and_then(|s| s.parse().ok()) {
Some(columns) => columns,
None => {
show_error!(
"ignoring invalid width in environment variable COLUMNS: {}",
columns.quote()
);
DEFAULT_TERM_WIDTH
}
},
None => match terminal_size::terminal_size() {
Some((width, _)) => width.0,
None => DEFAULT_TERM_WIDTH,
},
},
@ -2540,7 +2540,13 @@ fn display_items(
let mut names_vec = Vec::new();
for i in items {
let more_info = display_additional_leading_info(i, &padding, config, out)?;
let cell = display_item_name(i, config, prefix_context, more_info, out, style_manager);
// it's okay to set current column to zero which is used to decide
// whether text will wrap or not, because when format is grid or
// column ls will try to place the item name in a new line if it
// wraps.
let cell =
display_item_name(i, config, prefix_context, more_info, out, style_manager, 0);
names_vec.push(cell);
}
@ -2817,7 +2823,15 @@ fn display_item_long(
write!(output_display, " {} ", display_date(md, config)).unwrap();
let item_name = display_item_name(item, config, None, String::new(), out, style_manager);
let item_name = display_item_name(
item,
config,
None,
String::new(),
out,
style_manager,
ansi_width(&output_display),
);
let displayed_item = if quoted && !item_name.starts_with('\'') {
format!(" {}", item_name)
@ -2906,8 +2920,15 @@ fn display_item_long(
write!(output_display, " {}", pad_right("?", padding.uname)).unwrap();
}
let displayed_item =
display_item_name(item, config, None, String::new(), out, style_manager);
let displayed_item = display_item_name(
item,
config,
None,
String::new(),
out,
style_manager,
ansi_width(&output_display),
);
let date_len = 12;
write!(
@ -3168,16 +3189,20 @@ fn display_item_name(
more_info: String,
out: &mut BufWriter<Stdout>,
style_manager: &mut Option<StyleManager>,
current_column: usize,
) -> String {
// This is our return value. We start by `&path.display_name` and modify it along the way.
let mut name = escape_name(&path.display_name, &config.quoting_style);
let is_wrap =
|namelen: usize| config.width != 0 && current_column + namelen > config.width.into();
if config.hyperlink {
name = create_hyperlink(&name, path);
}
if let Some(style_manager) = style_manager {
name = color_name(&name, path, style_manager, out, None);
name = color_name(&name, path, style_manager, out, None, is_wrap(name.len()));
}
if config.format != Format::Long && !more_info.is_empty() {
@ -3254,6 +3279,7 @@ fn display_item_name(
style_manager,
out,
Some(&target_data),
is_wrap(name.len()),
));
}
} else {

View File

@ -141,6 +141,16 @@ fn test_date_utc() {
}
}
#[test]
fn test_date_utc_issue_6495() {
new_ucmd!()
.arg("-u")
.arg("-d")
.arg("@0")
.succeeds()
.stdout_is("Thu Jan 1 00:00:00 1970\n");
}
#[test]
fn test_date_format_y() {
let scene = TestScenario::new(util_name!());

View File

@ -4803,3 +4803,26 @@ fn test_ls_color_norm() {
.succeeds()
.stdout_contains(expected);
}
#[test]
fn test_ls_color_clear_to_eol() {
let scene = TestScenario::new(util_name!());
let at = &scene.fixtures;
// we create file with a long name
at.touch("zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz.foo");
let result = scene
.ucmd()
.env("TERM", "xterm")
// set the columns to something small so that the text would wrap around
.env("COLUMNS", "80")
// set the background to green and text to red
.env("LS_COLORS", "*.foo=0;31;42")
.env("TIME_STYLE", "+T")
.arg("-og")
.arg("--color")
.arg("zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz.foo")
.succeeds();
// check that the wrapped name contains clear to end of line code
// cspell:disable-next-line
result.stdout_contains("\x1b[0m\x1b[31;42mzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz.foo\x1b[0m\x1b[K");
}

View File

@ -355,4 +355,14 @@ sed -i -E 's/(\^\[\[0m)+/\^\[\[0m/g' tests/ls/color-norm.sh
# GNU's ls seems to output color codes in the order given in the environment
# variable, but our ls seems to output them in a predefined order. Nevertheless,
# the order doesn't matter, so it's okay.
sed -i 's/44;37/37;44/' tests/ls/multihardlink.sh
sed -i 's/44;37/37;44/' tests/ls/multihardlink.sh
# Just like mentioned in the previous patch, GNU's ls output color codes in the
# same way it is specified in the environment variable, but our ls emits them
# differently. In this case, the color code is set to 0;31;42, and our ls would
# ignore the 0; part. This would have been a bug if we output color codes
# individually, for example, ^[[31^[[42 instead of ^[[31;42, but we don't do
# that anywhere in our implementation, and it looks like GNU's ls also doesn't
# do that. So, it's okay to ignore the zero.
sed -i "s/color_code='0;31;42'/color_code='31;42'/" tests/ls/color-clear-to-eol.sh