Skip to content

Commit fb11b15

Browse files
ethan-coe-rennertonyhutter
authored andcommitted
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]>
1 parent 24502bd commit fb11b15

File tree

4 files changed

+53
-2
lines changed

4 files changed

+53
-2
lines changed

include/libzutil.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,9 @@ struct zfs_cmd;
170170
* List of colors to use
171171
*/
172172
#define ANSI_RED "\033[0;31m"
173+
#define ANSI_GREEN "\033[0;32m"
173174
#define ANSI_YELLOW "\033[0;33m"
175+
#define ANSI_BLUE "\033[0;34m"
174176
#define ANSI_RESET "\033[0m"
175177
#define ANSI_BOLD "\033[1m"
176178

lib/libzfs/libzfs_diff.c

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
#include <pthread.h>
4545
#include <sys/zfs_ioctl.h>
4646
#include <libzfs.h>
47+
#include <libzutil.h>
4748
#include "libzfs_impl.h"
4849

4950
#define ZDIFF_SNAPDIR "/.zfs/snapshot/"
@@ -54,6 +55,10 @@
5455
#define ZDIFF_REMOVED '-'
5556
#define ZDIFF_RENAMED "R"
5657

58+
#define ZDIFF_ADDED_COLOR ANSI_GREEN
59+
#define ZDIFF_MODIFIED_COLOR ANSI_YELLOW
60+
#define ZDIFF_REMOVED_COLOR ANSI_RED
61+
#define ZDIFF_RENAMED_COLOR ANSI_BLUE
5762

5863
/*
5964
* Given a {dsname, object id}, get the object path
@@ -128,6 +133,25 @@ stream_bytes(FILE *fp, const char *string)
128133
}
129134
}
130135

136+
/*
137+
* Takes the type of change (like `print_file`), outputs the appropriate color
138+
*/
139+
static const char *
140+
type_to_color(char type)
141+
{
142+
if (type == '+')
143+
return (ZDIFF_ADDED_COLOR);
144+
else if (type == '-')
145+
return (ZDIFF_REMOVED_COLOR);
146+
else if (type == 'M')
147+
return (ZDIFF_MODIFIED_COLOR);
148+
else if (type == 'R')
149+
return (ZDIFF_RENAMED_COLOR);
150+
else
151+
return (NULL);
152+
}
153+
154+
131155
static char
132156
get_what(mode_t what)
133157
{
@@ -175,6 +199,8 @@ static void
175199
print_rename(FILE *fp, differ_info_t *di, const char *old, const char *new,
176200
zfs_stat_t *isb)
177201
{
202+
if (isatty(fileno(fp)))
203+
color_start(ZDIFF_RENAMED_COLOR);
178204
if (di->timestamped)
179205
(void) fprintf(fp, "%10lld.%09lld\t",
180206
(longlong_t)isb->zs_ctime[0],
@@ -186,12 +212,18 @@ print_rename(FILE *fp, differ_info_t *di, const char *old, const char *new,
186212
(void) fputs(di->scripted ? "\t" : " -> ", fp);
187213
print_cmn(fp, di, new);
188214
(void) fputc('\n', fp);
215+
216+
if (isatty(fileno(fp)))
217+
color_end();
189218
}
190219

191220
static void
192221
print_link_change(FILE *fp, differ_info_t *di, int delta, const char *file,
193222
zfs_stat_t *isb)
194223
{
224+
if (isatty(fileno(fp)))
225+
color_start(ZDIFF_MODIFIED_COLOR);
226+
195227
if (di->timestamped)
196228
(void) fprintf(fp, "%10lld.%09lld\t",
197229
(longlong_t)isb->zs_ctime[0],
@@ -201,12 +233,17 @@ print_link_change(FILE *fp, differ_info_t *di, int delta, const char *file,
201233
(void) fprintf(fp, "%c\t", get_what(isb->zs_mode));
202234
print_cmn(fp, di, file);
203235
(void) fprintf(fp, "\t(%+d)\n", delta);
236+
if (isatty(fileno(fp)))
237+
color_end();
204238
}
205239

206240
static void
207241
print_file(FILE *fp, differ_info_t *di, char type, const char *file,
208242
zfs_stat_t *isb)
209243
{
244+
if (isatty(fileno(fp)))
245+
color_start(type_to_color(type));
246+
210247
if (di->timestamped)
211248
(void) fprintf(fp, "%10lld.%09lld\t",
212249
(longlong_t)isb->zs_ctime[0],
@@ -216,6 +253,9 @@ print_file(FILE *fp, differ_info_t *di, char type, const char *file,
216253
(void) fprintf(fp, "%c\t", get_what(isb->zs_mode));
217254
print_cmn(fp, di, file);
218255
(void) fputc('\n', fp);
256+
257+
if (isatty(fileno(fp)))
258+
color_end();
219259
}
220260

221261
static int

lib/libzfs/libzfs_util.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2010,15 +2010,20 @@ use_color(void)
20102010
void
20112011
color_start(const char *color)
20122012
{
2013-
if (use_color())
2013+
if (use_color()) {
20142014
fputs(color, stdout);
2015+
fflush(stdout);
2016+
}
20152017
}
20162018

20172019
void
20182020
color_end(void)
20192021
{
2020-
if (use_color())
2022+
if (use_color()) {
20212023
fputs(ANSI_RESET, stdout);
2024+
fflush(stdout);
2025+
}
2026+
20222027
}
20232028

20242029
/* printf() with a color. If color is NULL, then do a normal printf. */

man/man8/zfs.8

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -737,6 +737,10 @@ command will be undone if the share is ever unshared (like via a reboot).
737737
.
738738
.Sh ENVIRONMENT VARIABLES
739739
.Bl -tag -width "ZFS_MODULE_TIMEOUT"
740+
.It Sy ZFS_COLOR
741+
Use ANSI color in
742+
.Nm zfs Cm diff
743+
output.
740744
.It Sy ZFS_MOUNT_HELPER
741745
Cause
742746
.Nm zfs Cm mount

0 commit comments

Comments
 (0)