Deleted Added
full compact
propedit-cmd.c (302408) propedit-cmd.c (362181)
1/*
2 * propedit-cmd.c -- Edit properties of files/dirs using $EDITOR
3 *
4 * ====================================================================
5 * Licensed to the Apache Software Foundation (ASF) under one
6 * or more contributor license agreements. See the NOTICE file
7 * distributed with this work for additional information
8 * regarding copyright ownership. The ASF licenses this file

--- 33 unchanged lines hidden (view full) ---

42
43#include "private/svn_cmdline_private.h"
44#include "svn_private_config.h"
45
46
47/*** Code. ***/
48struct commit_info_baton
49{
1/*
2 * propedit-cmd.c -- Edit properties of files/dirs using $EDITOR
3 *
4 * ====================================================================
5 * Licensed to the Apache Software Foundation (ASF) under one
6 * or more contributor license agreements. See the NOTICE file
7 * distributed with this work for additional information
8 * regarding copyright ownership. The ASF licenses this file

--- 33 unchanged lines hidden (view full) ---

42
43#include "private/svn_cmdline_private.h"
44#include "svn_private_config.h"
45
46
47/*** Code. ***/
48struct commit_info_baton
49{
50 const char *pname_utf8;
50 const char *pname;
51 const char *target_local;
52};
53
54static svn_error_t *
55commit_info_handler(const svn_commit_info_t *commit_info,
56 void *baton,
57 apr_pool_t *pool)
58{
59 struct commit_info_baton *cib = baton;
60
61 SVN_ERR(svn_cmdline_printf(pool,
62 _("Set new value for property '%s' on '%s'\n"),
51 const char *target_local;
52};
53
54static svn_error_t *
55commit_info_handler(const svn_commit_info_t *commit_info,
56 void *baton,
57 apr_pool_t *pool)
58{
59 struct commit_info_baton *cib = baton;
60
61 SVN_ERR(svn_cmdline_printf(pool,
62 _("Set new value for property '%s' on '%s'\n"),
63 cib->pname_utf8, cib->target_local));
63 cib->pname, cib->target_local));
64 SVN_ERR(svn_cl__print_commit_info(commit_info, NULL, pool));
65
66 return SVN_NO_ERROR;
67}
68
69/* This implements the `svn_opt_subcommand_t' interface. */
70svn_error_t *
71svn_cl__propedit(apr_getopt_t *os,
72 void *baton,
73 apr_pool_t *pool)
74{
75 svn_cl__opt_state_t *opt_state = ((svn_cl__cmd_baton_t *) baton)->opt_state;
76 svn_client_ctx_t *ctx = ((svn_cl__cmd_baton_t *) baton)->ctx;
64 SVN_ERR(svn_cl__print_commit_info(commit_info, NULL, pool));
65
66 return SVN_NO_ERROR;
67}
68
69/* This implements the `svn_opt_subcommand_t' interface. */
70svn_error_t *
71svn_cl__propedit(apr_getopt_t *os,
72 void *baton,
73 apr_pool_t *pool)
74{
75 svn_cl__opt_state_t *opt_state = ((svn_cl__cmd_baton_t *) baton)->opt_state;
76 svn_client_ctx_t *ctx = ((svn_cl__cmd_baton_t *) baton)->ctx;
77 const char *pname, *pname_utf8;
77 const char *pname;
78 apr_array_header_t *args, *targets;
79
80 /* Validate the input and get the property's name (and a UTF-8
81 version of that name). */
82 SVN_ERR(svn_opt_parse_num_args(&args, os, 1, pool));
83 pname = APR_ARRAY_IDX(args, 0, const char *);
78 apr_array_header_t *args, *targets;
79
80 /* Validate the input and get the property's name (and a UTF-8
81 version of that name). */
82 SVN_ERR(svn_opt_parse_num_args(&args, os, 1, pool));
83 pname = APR_ARRAY_IDX(args, 0, const char *);
84 SVN_ERR(svn_utf_cstring_to_utf8(&pname_utf8, pname, pool));
85 if (! svn_prop_name_is_valid(pname_utf8))
84 SVN_ERR(svn_utf_cstring_to_utf8(&pname, pname, pool));
85 if (! svn_prop_name_is_valid(pname))
86 return svn_error_createf(SVN_ERR_CLIENT_PROPERTY_NAME, NULL,
87 _("'%s' is not a valid Subversion property name"),
86 return svn_error_createf(SVN_ERR_CLIENT_PROPERTY_NAME, NULL,
87 _("'%s' is not a valid Subversion property name"),
88 pname_utf8);
88 pname);
89 if (!opt_state->force)
89 if (!opt_state->force)
90 SVN_ERR(svn_cl__check_svn_prop_name(pname_utf8, opt_state->revprop,
90 SVN_ERR(svn_cl__check_svn_prop_name(pname, opt_state->revprop,
91 svn_cl__prop_use_edit, pool));
92
91 svn_cl__prop_use_edit, pool));
92
93 if (opt_state->encoding && !svn_prop_needs_translation(pname_utf8))
93 if (opt_state->encoding && !svn_prop_needs_translation(pname))
94 return svn_error_create
95 (SVN_ERR_UNSUPPORTED_FEATURE, NULL,
96 _("--encoding option applies only to textual"
97 " Subversion-controlled properties"));
98
99 /* Suck up all the remaining arguments into a targets array */
100 SVN_ERR(svn_cl__args_to_target_array_print_reserved(&targets, os,
101 opt_state->targets,

--- 13 unchanged lines hidden (view full) ---

115 /* Implicit "." is okay for revision properties; it just helps
116 us find the right repository. */
117 svn_opt_push_implicit_dot_target(targets, pool);
118
119 SVN_ERR(svn_cl__revprop_prepare(&opt_state->start_revision, targets,
120 &URL, ctx, pool));
121
122 /* Fetch the current property. */
94 return svn_error_create
95 (SVN_ERR_UNSUPPORTED_FEATURE, NULL,
96 _("--encoding option applies only to textual"
97 " Subversion-controlled properties"));
98
99 /* Suck up all the remaining arguments into a targets array */
100 SVN_ERR(svn_cl__args_to_target_array_print_reserved(&targets, os,
101 opt_state->targets,

--- 13 unchanged lines hidden (view full) ---

115 /* Implicit "." is okay for revision properties; it just helps
116 us find the right repository. */
117 svn_opt_push_implicit_dot_target(targets, pool);
118
119 SVN_ERR(svn_cl__revprop_prepare(&opt_state->start_revision, targets,
120 &URL, ctx, pool));
121
122 /* Fetch the current property. */
123 SVN_ERR(svn_client_revprop_get(pname_utf8, &propval,
123 SVN_ERR(svn_client_revprop_get(pname, &propval,
124 URL, &(opt_state->start_revision),
125 &rev, ctx, pool));
126
127 if (! propval)
128 {
129 propval = svn_string_create_empty(pool);
130 /* This is how we signify to svn_client_revprop_set2() that
131 we want it to check that the original value hasn't

--- 8 unchanged lines hidden (view full) ---

140 /* Run the editor on a temporary file which contains the
141 original property value... */
142 SVN_ERR(svn_io_temp_dir(&temp_dir, pool));
143 SVN_ERR(svn_cmdline__edit_string_externally(
144 &propval, NULL,
145 opt_state->editor_cmd, temp_dir,
146 propval, "svn-prop",
147 ctx->config,
124 URL, &(opt_state->start_revision),
125 &rev, ctx, pool));
126
127 if (! propval)
128 {
129 propval = svn_string_create_empty(pool);
130 /* This is how we signify to svn_client_revprop_set2() that
131 we want it to check that the original value hasn't

--- 8 unchanged lines hidden (view full) ---

140 /* Run the editor on a temporary file which contains the
141 original property value... */
142 SVN_ERR(svn_io_temp_dir(&temp_dir, pool));
143 SVN_ERR(svn_cmdline__edit_string_externally(
144 &propval, NULL,
145 opt_state->editor_cmd, temp_dir,
146 propval, "svn-prop",
147 ctx->config,
148 svn_prop_needs_translation(pname_utf8),
148 svn_prop_needs_translation(pname),
149 opt_state->encoding, pool));
150
151 /* ...and re-set the property's value accordingly. */
152 if (propval)
153 {
149 opt_state->encoding, pool));
150
151 /* ...and re-set the property's value accordingly. */
152 if (propval)
153 {
154 SVN_ERR(svn_client_revprop_set2(pname_utf8,
154 SVN_ERR(svn_client_revprop_set2(pname,
155 propval, &original_propval,
156 URL, &(opt_state->start_revision),
157 &rev, opt_state->force, ctx, pool));
158
159 SVN_ERR
160 (svn_cmdline_printf
161 (pool,
162 _("Set new value for property '%s' on revision %ld\n"),
155 propval, &original_propval,
156 URL, &(opt_state->start_revision),
157 &rev, opt_state->force, ctx, pool));
158
159 SVN_ERR
160 (svn_cmdline_printf
161 (pool,
162 _("Set new value for property '%s' on revision %ld\n"),
163 pname_utf8, rev));
163 pname, rev));
164 }
165 else
166 {
167 SVN_ERR(svn_cmdline_printf
168 (pool, _("No changes to property '%s' on revision %ld\n"),
164 }
165 else
166 {
167 SVN_ERR(svn_cmdline_printf
168 (pool, _("No changes to property '%s' on revision %ld\n"),
169 pname_utf8, rev));
169 pname, rev));
170 }
171 }
172 else if (opt_state->start_revision.kind != svn_opt_revision_unspecified)
173 {
174 return svn_error_createf
175 (SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
176 _("Cannot specify revision for editing versioned property '%s'"),
170 }
171 }
172 else if (opt_state->start_revision.kind != svn_opt_revision_unspecified)
173 {
174 return svn_error_createf
175 (SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
176 _("Cannot specify revision for editing versioned property '%s'"),
177 pname_utf8);
177 pname);
178 }
179 else /* operate on a normal, versioned property (not a revprop) */
180 {
181 apr_pool_t *subpool = svn_pool_create(pool);
182 struct commit_info_baton cib;
183 int i;
184
185 /* The customary implicit dot rule has been prone to user error

--- 15 unchanged lines hidden (view full) ---

201 {
202 return svn_error_create
203 (SVN_ERR_CL_INSUFFICIENT_ARGS, NULL,
204 _("Explicit target argument required"));
205 }
206
207 SVN_ERR(svn_cl__eat_peg_revisions(&targets, targets, pool));
208
178 }
179 else /* operate on a normal, versioned property (not a revprop) */
180 {
181 apr_pool_t *subpool = svn_pool_create(pool);
182 struct commit_info_baton cib;
183 int i;
184
185 /* The customary implicit dot rule has been prone to user error

--- 15 unchanged lines hidden (view full) ---

201 {
202 return svn_error_create
203 (SVN_ERR_CL_INSUFFICIENT_ARGS, NULL,
204 _("Explicit target argument required"));
205 }
206
207 SVN_ERR(svn_cl__eat_peg_revisions(&targets, targets, pool));
208
209 cib.pname_utf8 = pname_utf8;
209 cib.pname = pname;
210
211 /* For each target, edit the property PNAME. */
212 for (i = 0; i < targets->nelts; i++)
213 {
214 apr_hash_t *props;
215 const char *target = APR_ARRAY_IDX(targets, i, const char *);
216 svn_string_t *propval, *edited_propval;
217 const char *base_dir = target;

--- 11 unchanged lines hidden (view full) ---

229 else
230 abspath_or_url = target;
231
232 /* Propedits can only happen on HEAD or the working copy, so
233 the peg revision can be as unspecified. */
234 peg_revision.kind = svn_opt_revision_unspecified;
235
236 /* Fetch the current property. */
210
211 /* For each target, edit the property PNAME. */
212 for (i = 0; i < targets->nelts; i++)
213 {
214 apr_hash_t *props;
215 const char *target = APR_ARRAY_IDX(targets, i, const char *);
216 svn_string_t *propval, *edited_propval;
217 const char *base_dir = target;

--- 11 unchanged lines hidden (view full) ---

229 else
230 abspath_or_url = target;
231
232 /* Propedits can only happen on HEAD or the working copy, so
233 the peg revision can be as unspecified. */
234 peg_revision.kind = svn_opt_revision_unspecified;
235
236 /* Fetch the current property. */
237 SVN_ERR(svn_client_propget5(&props, NULL, pname_utf8, abspath_or_url,
237 SVN_ERR(svn_client_propget5(&props, NULL, pname, abspath_or_url,
238 &peg_revision,
239 &(opt_state->start_revision),
240 &base_rev, svn_depth_empty,
241 NULL, ctx, subpool, subpool));
242
243 /* Get the property value. */
244 propval = svn_hash_gets(props, abspath_or_url);
245 if (! propval)

--- 31 unchanged lines hidden (view full) ---

277 original property value... */
278 SVN_ERR(svn_cmdline__edit_string_externally(&edited_propval, NULL,
279 opt_state->editor_cmd,
280 base_dir,
281 propval,
282 "svn-prop",
283 ctx->config,
284 svn_prop_needs_translation
238 &peg_revision,
239 &(opt_state->start_revision),
240 &base_rev, svn_depth_empty,
241 NULL, ctx, subpool, subpool));
242
243 /* Get the property value. */
244 propval = svn_hash_gets(props, abspath_or_url);
245 if (! propval)

--- 31 unchanged lines hidden (view full) ---

277 original property value... */
278 SVN_ERR(svn_cmdline__edit_string_externally(&edited_propval, NULL,
279 opt_state->editor_cmd,
280 base_dir,
281 propval,
282 "svn-prop",
283 ctx->config,
284 svn_prop_needs_translation
285 (pname_utf8),
285 (pname),
286 opt_state->encoding,
287 subpool));
288
289 target_local = svn_path_is_url(target) ? target
290 : svn_dirent_local_style(target, subpool);
291 cib.target_local = target_local;
292
293 /* ...and re-set the property's value accordingly. */
294 if (edited_propval && !svn_string_compare(propval, edited_propval))
295 {
296 svn_error_t *err = SVN_NO_ERROR;
297
286 opt_state->encoding,
287 subpool));
288
289 target_local = svn_path_is_url(target) ? target
290 : svn_dirent_local_style(target, subpool);
291 cib.target_local = target_local;
292
293 /* ...and re-set the property's value accordingly. */
294 if (edited_propval && !svn_string_compare(propval, edited_propval))
295 {
296 svn_error_t *err = SVN_NO_ERROR;
297
298 svn_cl__check_boolean_prop_val(pname_utf8, edited_propval->data,
298 svn_cl__check_boolean_prop_val(pname, edited_propval->data,
299 subpool);
300
301 if (ctx->log_msg_func3)
302 SVN_ERR(svn_cl__make_log_msg_baton(&(ctx->log_msg_baton3),
303 opt_state, NULL, ctx->config,
304 subpool));
305 if (svn_path_is_url(target))
306 {
299 subpool);
300
301 if (ctx->log_msg_func3)
302 SVN_ERR(svn_cl__make_log_msg_baton(&(ctx->log_msg_baton3),
303 opt_state, NULL, ctx->config,
304 subpool));
305 if (svn_path_is_url(target))
306 {
307 err = svn_client_propset_remote(pname_utf8, edited_propval,
307 err = svn_client_propset_remote(pname, edited_propval,
308 target, opt_state->force,
309 base_rev,
310 opt_state->revprop_table,
311 commit_info_handler, &cib,
312 ctx, subpool);
313 }
314 else
315 {
316 apr_array_header_t *targs = apr_array_make(subpool, 1,
317 sizeof(const char *));
318
319 APR_ARRAY_PUSH(targs, const char *) = target;
320
321 SVN_ERR(svn_cl__propset_print_binary_mime_type_warning(
308 target, opt_state->force,
309 base_rev,
310 opt_state->revprop_table,
311 commit_info_handler, &cib,
312 ctx, subpool);
313 }
314 else
315 {
316 apr_array_header_t *targs = apr_array_make(subpool, 1,
317 sizeof(const char *));
318
319 APR_ARRAY_PUSH(targs, const char *) = target;
320
321 SVN_ERR(svn_cl__propset_print_binary_mime_type_warning(
322 targs, pname_utf8, propval, subpool));
322 targs, pname, propval, subpool));
323
323
324 err = svn_client_propset_local(pname_utf8, edited_propval,
324 err = svn_client_propset_local(pname, edited_propval,
325 targs, svn_depth_empty,
326 opt_state->force, NULL,
327 ctx, subpool);
328 }
329
330 if (ctx->log_msg_func3)
331 SVN_ERR(svn_cl__cleanup_log_msg(ctx->log_msg_baton3,
332 err, pool));
333 else if (err)
334 return svn_error_trace(err);
335
336 /* Print a message if we successfully committed or if it
337 was just a wc propset (but not if the user aborted a URL
338 propedit). */
339 if (!svn_path_is_url(target))
340 SVN_ERR(svn_cmdline_printf(
341 subpool, _("Set new value for property '%s' on '%s'\n"),
325 targs, svn_depth_empty,
326 opt_state->force, NULL,
327 ctx, subpool);
328 }
329
330 if (ctx->log_msg_func3)
331 SVN_ERR(svn_cl__cleanup_log_msg(ctx->log_msg_baton3,
332 err, pool));
333 else if (err)
334 return svn_error_trace(err);
335
336 /* Print a message if we successfully committed or if it
337 was just a wc propset (but not if the user aborted a URL
338 propedit). */
339 if (!svn_path_is_url(target))
340 SVN_ERR(svn_cmdline_printf(
341 subpool, _("Set new value for property '%s' on '%s'\n"),
342 pname_utf8, target_local));
342 pname, target_local));
343 }
344 else
345 {
346 SVN_ERR
347 (svn_cmdline_printf
348 (subpool, _("No changes to property '%s' on '%s'\n"),
343 }
344 else
345 {
346 SVN_ERR
347 (svn_cmdline_printf
348 (subpool, _("No changes to property '%s' on '%s'\n"),
349 pname_utf8, target_local));
349 pname, target_local));
350 }
351 }
352 svn_pool_destroy(subpool);
353 }
354
355 return SVN_NO_ERROR;
356}
350 }
351 }
352 svn_pool_destroy(subpool);
353 }
354
355 return SVN_NO_ERROR;
356}