2
* feedback.c: feedback handlers for cmdline client.
4
* ====================================================================
5
* Copyright (c) 2000-2004 CollabNet. All rights reserved.
7
* This software is licensed as described in the file COPYING, which
8
* you should have received as part of this distribution. The terms
9
* are also available at http://subversion.tigris.org/license-1.html.
10
* If newer versions of this license are posted there, you may use a
11
* newer version instead, at your option.
13
* This software consists of voluntary contributions made by many
14
* individuals. For exact contribution history, see the revision
15
* history and logs, available at http://subversion.tigris.org/.
16
* ====================================================================
19
/* ==================================================================== */
25
#define APR_WANT_STDIO
26
#define APR_WANT_STRFUNC
29
#include "svn_cmdline.h"
30
#include "svn_pools.h"
34
#include "svn_private_config.h"
37
/* Baton for notify and friends. */
40
svn_boolean_t received_some_change;
41
svn_boolean_t is_checkout;
42
svn_boolean_t is_export;
43
svn_boolean_t suppress_final_line;
44
svn_boolean_t sent_first_txdelta;
45
svn_boolean_t in_external;
46
svn_boolean_t had_print_error; /* Used to not keep printing error messages
47
when we've already had one print error. */
51
/* This implements `svn_wc_notify_func2_t'.
52
* NOTE: This function can't fail, so we just ignore any print errors. */
54
notify (void *baton, const svn_wc_notify_t *n, apr_pool_t *pool)
56
struct notify_baton *nb = baton;
57
char statchar_buf[5] = " ";
58
const char *path_local;
61
path_local = svn_path_local_style (n->path, pool);
65
case svn_wc_notify_skip:
66
if (n->content_state == svn_wc_notify_state_missing)
68
if ((err = svn_cmdline_printf
69
(pool, _("Skipped missing target: '%s'\n"),
75
if ((err = svn_cmdline_printf
76
(pool, _("Skipped '%s'\n"), path_local)))
81
case svn_wc_notify_update_delete:
82
nb->received_some_change = TRUE;
83
if ((err = svn_cmdline_printf (pool, "D %s\n", path_local)))
87
case svn_wc_notify_update_add:
88
nb->received_some_change = TRUE;
89
if ((err = svn_cmdline_printf (pool, "A %s\n", path_local)))
93
case svn_wc_notify_restore:
94
if ((err = svn_cmdline_printf (pool, _("Restored '%s'\n"),
99
case svn_wc_notify_revert:
100
if ((err = svn_cmdline_printf (pool, _("Reverted '%s'\n"),
105
case svn_wc_notify_failed_revert:
106
if (( err = svn_cmdline_printf (pool, _("Failed to revert '%s' -- "
107
"try updating instead.\n"),
112
case svn_wc_notify_resolved:
113
if ((err = svn_cmdline_printf (pool,
114
_("Resolved conflicted state of '%s'\n"),
119
case svn_wc_notify_add:
120
/* We *should* only get the MIME_TYPE if PATH is a file. If we
121
do get it, and the mime-type is not textual, note that this
122
is a binary addition. */
123
if (n->mime_type && (svn_mime_type_is_binary (n->mime_type)))
125
if ((err = svn_cmdline_printf (pool, "A (bin) %s\n",
131
if ((err = svn_cmdline_printf (pool, "A %s\n",
137
case svn_wc_notify_delete:
138
nb->received_some_change = TRUE;
139
if ((err = svn_cmdline_printf (pool, "D %s\n",
144
case svn_wc_notify_update_update:
146
/* If this is an inoperative dir change, do no notification.
147
An inoperative dir change is when a directory gets closed
148
without any props having been changed. */
149
if (! ((n->kind == svn_node_dir)
150
&& ((n->prop_state == svn_wc_notify_state_inapplicable)
151
|| (n->prop_state == svn_wc_notify_state_unknown)
152
|| (n->prop_state == svn_wc_notify_state_unchanged))))
154
if (n->kind == svn_node_file)
156
if (n->content_state == svn_wc_notify_state_conflicted)
157
statchar_buf[0] = 'C';
158
else if (n->content_state == svn_wc_notify_state_merged)
159
statchar_buf[0] = 'G';
160
else if (n->content_state == svn_wc_notify_state_changed)
161
statchar_buf[0] = 'U';
164
if (n->prop_state == svn_wc_notify_state_conflicted)
165
statchar_buf[1] = 'C';
166
else if (n->prop_state == svn_wc_notify_state_merged)
167
statchar_buf[1] = 'G';
168
else if (n->prop_state == svn_wc_notify_state_changed)
169
statchar_buf[1] = 'U';
171
if (n->lock_state == svn_wc_notify_lock_state_unlocked)
172
statchar_buf[2] = 'B';
174
if (statchar_buf[0] != ' ' || statchar_buf[1] != ' ')
175
nb->received_some_change = TRUE;
177
if (statchar_buf[0] != ' ' || statchar_buf[1] != ' '
178
|| statchar_buf[2] != ' ')
180
if ((err = svn_cmdline_printf (pool, "%s %s\n",
181
statchar_buf, path_local)))
188
case svn_wc_notify_update_external:
189
/* Remember that we're now "inside" an externals definition. */
190
nb->in_external = TRUE;
192
/* Currently this is used for checkouts and switches too. If we
193
want different output, we'll have to add new actions. */
194
if ((err = svn_cmdline_printf (pool,
195
_("\nFetching external item into '%s'\n"),
200
case svn_wc_notify_update_completed:
202
if (! nb->suppress_final_line)
204
if (SVN_IS_VALID_REVNUM (n->revision))
208
if ((err = svn_cmdline_printf
209
(pool, nb->in_external
210
? _("Exported external at revision %ld.\n")
211
: _("Exported revision %ld.\n"),
215
else if (nb->is_checkout)
217
if ((err = svn_cmdline_printf
218
(pool, nb->in_external
219
? _("Checked out external at revision %ld.\n")
220
: _("Checked out revision %ld.\n"),
226
if (nb->received_some_change)
228
if ((err = svn_cmdline_printf
229
(pool, nb->in_external
230
? _("Updated external to revision %ld.\n")
231
: _("Updated to revision %ld.\n"),
237
if ((err = svn_cmdline_printf
238
(pool, nb->in_external
239
? _("External at revision %ld.\n")
240
: _("At revision %ld.\n"),
246
else /* no revision */
250
if ((err = svn_cmdline_printf
251
(pool, nb->in_external
252
? _("External export complete.\n")
253
: _("Export complete.\n"))))
256
else if (nb->is_checkout)
258
if ((err = svn_cmdline_printf
259
(pool, nb->in_external
260
? _("External checkout complete.\n")
261
: _("Checkout complete.\n"))))
266
if ((err = svn_cmdline_printf
267
(pool, nb->in_external
268
? _("External update complete.\n")
269
: _("Update complete.\n"))))
277
nb->in_external = FALSE;
278
if ((err = svn_cmdline_printf (pool, "\n")))
283
case svn_wc_notify_status_external:
284
if ((err = svn_cmdline_printf
285
(pool, _("\nPerforming status on external item at '%s'\n"),
290
case svn_wc_notify_status_completed:
291
if (SVN_IS_VALID_REVNUM (n->revision))
292
if ((err = svn_cmdline_printf (pool,
293
_("Status against revision: %6ld\n"),
298
case svn_wc_notify_commit_modified:
299
/* xgettext: Align the %s's on this and the following 4 messages */
300
if ((err = svn_cmdline_printf (pool,
306
case svn_wc_notify_commit_added:
307
if (n->mime_type && svn_mime_type_is_binary (n->mime_type))
309
if ((err = svn_cmdline_printf (pool,
310
_("Adding (bin) %s\n"),
316
if ((err = svn_cmdline_printf (pool,
323
case svn_wc_notify_commit_deleted:
324
if ((err = svn_cmdline_printf (pool, _("Deleting %s\n"),
329
case svn_wc_notify_commit_replaced:
330
if ((err = svn_cmdline_printf (pool,
336
case svn_wc_notify_commit_postfix_txdelta:
337
if (! nb->sent_first_txdelta)
339
nb->sent_first_txdelta = TRUE;
340
if ((err = svn_cmdline_printf (pool,
341
_("Transmitting file data "))))
345
if ((err = svn_cmdline_printf (pool, ".")))
350
case svn_wc_notify_locked:
351
if ((err = svn_cmdline_printf (pool, _("'%s' locked by user '%s'.\n"),
352
n->path, n->lock->owner)))
356
case svn_wc_notify_unlocked:
357
if ((err = svn_cmdline_printf (pool, _("'%s' unlocked.\n"),
362
case svn_wc_notify_failed_lock:
363
case svn_wc_notify_failed_unlock:
364
svn_handle_error (n->err, stderr, FALSE);
374
/* If we had no errors before, print this error to stderr. Else, don't print
375
anything. The user already knows there were some output errors,
376
so there is no point in flooding her with an error per notification. */
377
if (!nb->had_print_error)
379
nb->had_print_error = TRUE;
380
svn_handle_error (err, stderr, FALSE);
382
svn_error_clear (err);
387
svn_cl__get_notifier (svn_wc_notify_func2_t *notify_func_p,
388
void **notify_baton_p,
389
svn_boolean_t is_checkout,
390
svn_boolean_t is_export,
391
svn_boolean_t suppress_final_line,
394
struct notify_baton *nb = apr_palloc (pool, sizeof (*nb));
396
nb->received_some_change = FALSE;
397
nb->sent_first_txdelta = FALSE;
398
nb->is_checkout = is_checkout;
399
nb->is_export = is_export;
400
nb->suppress_final_line = suppress_final_line;
401
nb->in_external = FALSE;
402
nb->had_print_error = FALSE;
404
*notify_func_p = notify;
405
*notify_baton_p = nb;