aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEthan Coe-Renner <[email protected]>2022-12-12 15:30:51 -0800
committerTony Hutter <[email protected]>2022-12-15 10:14:32 -0800
commitfb11b1570a473dfe864fcac71b5220a28503fa5d (patch)
treef1ee407d46abc4c4e0173187b991d7bf94ba9cf0
parent24502bd3a79d71b726f723ced55b0e7ccb5db840 (diff)
Add color output to zfs diff.
This adds support to color zfs diff (in the style of git diff) conditional on the ZFS_COLOR environment variable. Signed-off-by: Ethan Coe-Renner <[email protected]>
-rw-r--r--include/libzutil.h2
-rw-r--r--lib/libzfs/libzfs_diff.c40
-rw-r--r--lib/libzfs/libzfs_util.c9
-rw-r--r--man/man8/zfs.84
4 files changed, 53 insertions, 2 deletions
diff --git a/include/libzutil.h b/include/libzutil.h
index 617dd0cd1..e285183e0 100644
--- a/include/libzutil.h
+++ b/include/libzutil.h
@@ -170,7 +170,9 @@ struct zfs_cmd;
* List of colors to use
*/
#define ANSI_RED "\033[0;31m"
+#define ANSI_GREEN "\033[0;32m"
#define ANSI_YELLOW "\033[0;33m"
+#define ANSI_BLUE "\033[0;34m"
#define ANSI_RESET "\033[0m"
#define ANSI_BOLD "\033[1m"
diff --git a/lib/libzfs/libzfs_diff.c b/lib/libzfs/libzfs_diff.c
index 84e140ede..1330e7c30 100644
--- a/lib/libzfs/libzfs_diff.c
+++ b/lib/libzfs/libzfs_diff.c
@@ -44,6 +44,7 @@
#include <pthread.h>
#include <sys/zfs_ioctl.h>
#include <libzfs.h>
+#include <libzutil.h>
#include "libzfs_impl.h"
#define ZDIFF_SNAPDIR "/.zfs/snapshot/"
@@ -54,6 +55,10 @@
#define ZDIFF_REMOVED '-'
#define ZDIFF_RENAMED "R"
+#define ZDIFF_ADDED_COLOR ANSI_GREEN
+#define ZDIFF_MODIFIED_COLOR ANSI_YELLOW
+#define ZDIFF_REMOVED_COLOR ANSI_RED
+#define ZDIFF_RENAMED_COLOR ANSI_BLUE
/*
* Given a {dsname, object id}, get the object path
@@ -128,6 +133,25 @@ stream_bytes(FILE *fp, const char *string)
}
}
+/*
+ * Takes the type of change (like `print_file`), outputs the appropriate color
+ */
+static const char *
+type_to_color(char type)
+{
+ if (type == '+')
+ return (ZDIFF_ADDED_COLOR);
+ else if (type == '-')
+ return (ZDIFF_REMOVED_COLOR);
+ else if (type == 'M')
+ return (ZDIFF_MODIFIED_COLOR);
+ else if (type == 'R')
+ return (ZDIFF_RENAMED_COLOR);
+ else
+ return (NULL);
+}
+
+
static char
get_what(mode_t what)
{
@@ -175,6 +199,8 @@ static void
print_rename(FILE *fp, differ_info_t *di, const char *old, const char *new,
zfs_stat_t *isb)
{
+ if (isatty(fileno(fp)))
+ color_start(ZDIFF_RENAMED_COLOR);
if (di->timestamped)
(void) fprintf(fp, "%10lld.%09lld\t",
(longlong_t)isb->zs_ctime[0],
@@ -186,12 +212,18 @@ print_rename(FILE *fp, differ_info_t *di, const char *old, const char *new,
(void) fputs(di->scripted ? "\t" : " -> ", fp);
print_cmn(fp, di, new);
(void) fputc('\n', fp);
+
+ if (isatty(fileno(fp)))
+ color_end();
}
static void
print_link_change(FILE *fp, differ_info_t *di, int delta, const char *file,
zfs_stat_t *isb)
{
+ if (isatty(fileno(fp)))
+ color_start(ZDIFF_MODIFIED_COLOR);
+
if (di->timestamped)
(void) fprintf(fp, "%10lld.%09lld\t",
(longlong_t)isb->zs_ctime[0],
@@ -201,12 +233,17 @@ print_link_change(FILE *fp, differ_info_t *di, int delta, const char *file,
(void) fprintf(fp, "%c\t", get_what(isb->zs_mode));
print_cmn(fp, di, file);
(void) fprintf(fp, "\t(%+d)\n", delta);
+ if (isatty(fileno(fp)))
+ color_end();
}
static void
print_file(FILE *fp, differ_info_t *di, char type, const char *file,
zfs_stat_t *isb)
{
+ if (isatty(fileno(fp)))
+ color_start(type_to_color(type));
+
if (di->timestamped)
(void) fprintf(fp, "%10lld.%09lld\t",
(longlong_t)isb->zs_ctime[0],
@@ -216,6 +253,9 @@ print_file(FILE *fp, differ_info_t *di, char type, const char *file,
(void) fprintf(fp, "%c\t", get_what(isb->zs_mode));
print_cmn(fp, di, file);
(void) fputc('\n', fp);
+
+ if (isatty(fileno(fp)))
+ color_end();
}
static int
diff --git a/lib/libzfs/libzfs_util.c b/lib/libzfs/libzfs_util.c
index b4679dbb3..c31f18009 100644
--- a/lib/libzfs/libzfs_util.c
+++ b/lib/libzfs/libzfs_util.c
@@ -2010,15 +2010,20 @@ use_color(void)
void
color_start(const char *color)
{
- if (use_color())
+ if (use_color()) {
fputs(color, stdout);
+ fflush(stdout);
+ }
}
void
color_end(void)
{
- if (use_color())
+ if (use_color()) {
fputs(ANSI_RESET, stdout);
+ fflush(stdout);
+ }
+
}
/* printf() with a color. If color is NULL, then do a normal printf. */
diff --git a/man/man8/zfs.8 b/man/man8/zfs.8
index 52c079257..d12377f9b 100644
--- a/man/man8/zfs.8
+++ b/man/man8/zfs.8
@@ -737,6 +737,10 @@ command will be undone if the share is ever unshared (like via a reboot).
.
.Sh ENVIRONMENT VARIABLES
.Bl -tag -width "ZFS_MODULE_TIMEOUT"
+.It Sy ZFS_COLOR
+Use ANSI color in
+.Nm zfs Cm diff
+output.
.It Sy ZFS_MOUNT_HELPER
Cause
.Nm zfs Cm mount