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} |