/* This implements the `svn_opt_subcommand_t' interface. */ svn_error_t * svn_cl__proplist(apr_getopt_t *os, void *baton, apr_pool_t *scratch_pool) { svn_cl__opt_state_t *opt_state = ((svn_cl__cmd_baton_t *) baton)->opt_state; svn_client_ctx_t *ctx = ((svn_cl__cmd_baton_t *) baton)->ctx; apr_array_header_t *targets; SVN_ERR(svn_cl__args_to_target_array_print_reserved(&targets, os, opt_state->targets, ctx, FALSE, scratch_pool)); /* Add "." if user passed 0 file arguments */ svn_opt_push_implicit_dot_target(targets, scratch_pool); if (opt_state->revprop) /* operate on revprops */ { svn_revnum_t rev; const char *URL; apr_hash_t *proplist; SVN_ERR(svn_cl__revprop_prepare(&opt_state->start_revision, targets, &URL, ctx, scratch_pool)); /* Let libsvn_client do the real work. */ SVN_ERR(svn_client_revprop_list(&proplist, URL, &(opt_state->start_revision), &rev, ctx, scratch_pool)); if (opt_state->xml) { svn_stringbuf_t *sb = NULL; char *revstr = apr_psprintf(scratch_pool, "%ld", rev); SVN_ERR(svn_cl__xml_print_header("properties", scratch_pool)); svn_xml_make_open_tag(&sb, scratch_pool, svn_xml_normal, "revprops", "rev", revstr, NULL); SVN_ERR(svn_cl__print_xml_prop_hash (&sb, proplist, (! opt_state->verbose), scratch_pool)); svn_xml_make_close_tag(&sb, scratch_pool, "revprops"); SVN_ERR(svn_cl__error_checked_fputs(sb->data, stdout)); SVN_ERR(svn_cl__xml_print_footer("properties", scratch_pool)); } else { SVN_ERR (svn_cmdline_printf(scratch_pool, _("Unversioned properties on revision %ld:\n"), rev)); SVN_ERR(svn_cl__print_prop_hash (NULL, proplist, (! opt_state->verbose), scratch_pool)); } } else /* operate on normal, versioned properties (not revprops) */ { int i; apr_pool_t *iterpool; svn_proplist_receiver_t pl_receiver; svn_boolean_t had_errors = FALSE; if (opt_state->xml) { SVN_ERR(svn_cl__xml_print_header("properties", scratch_pool)); pl_receiver = proplist_receiver_xml; } else { pl_receiver = proplist_receiver; } if (opt_state->depth == svn_depth_unknown) opt_state->depth = svn_depth_empty; iterpool = svn_pool_create(scratch_pool); for (i = 0; i < targets->nelts; i++) { const char *target = APR_ARRAY_IDX(targets, i, const char *); proplist_baton_t pl_baton; const char *truepath; svn_opt_revision_t peg_revision; svn_boolean_t success; svn_pool_clear(iterpool); SVN_ERR(svn_cl__check_cancel(ctx->cancel_baton)); pl_baton.is_url = svn_path_is_url(target); pl_baton.opt_state = opt_state; /* Check for a peg revision. */ SVN_ERR(svn_opt_parse_path(&peg_revision, &truepath, target, iterpool)); SVN_ERR(svn_cl__try( svn_client_proplist3(truepath, &peg_revision, &(opt_state->start_revision), opt_state->depth, opt_state->changelists, pl_receiver, &pl_baton, ctx, iterpool), &success, opt_state->quiet, SVN_ERR_UNVERSIONED_RESOURCE, SVN_ERR_ENTRY_NOT_FOUND, SVN_NO_ERROR)); if (!success) had_errors = TRUE; } svn_pool_destroy(iterpool); if (opt_state->xml) SVN_ERR(svn_cl__xml_print_footer("properties", scratch_pool)); /* Error out *after* we closed the XML element */ if (had_errors) return svn_error_create(SVN_ERR_ILLEGAL_TARGET, NULL, _("Could not display info for all targets " "because some targets don't exist")); } return SVN_NO_ERROR; }
Py::Object pysvn_client::cmd_proplist( const Py::Tuple &a_args, const Py::Dict &a_kws ) { static argument_description args_desc[] = { { true, name_url_or_path }, { false, name_revision }, { false, name_recurse }, #if defined( PYSVN_HAS_CLIENT_PROPLIST2 ) { false, name_peg_revision }, #endif #if defined( PYSVN_HAS_CLIENT_PROPLIST3 ) { false, name_depth }, { false, name_changelists }, #endif { false, NULL } }; FunctionArguments args( "proplist", args_desc, a_args, a_kws ); args.check(); Py::List path_list( toListOfStrings( args.getArg( name_url_or_path ) ) ); SvnPool pool( m_context ); #if defined( PYSVN_HAS_CLIENT_PROPLIST3 ) apr_array_header_t *changelists = NULL; if( args.hasArg( name_changelists ) ) { changelists = arrayOfStringsFromListOfStrings( args.getArg( name_changelists ), pool ); } svn_depth_t depth = args.getDepth( name_depth, name_recurse, svn_depth_files, svn_depth_empty ); #else bool recurse = args.getBoolean( name_recurse, false ); #endif bool is_revision_setup = false; bool is_url = false; svn_opt_revision_t revision_url; svn_opt_revision_t revision_file; if( args.hasArg( name_revision ) ) { revision_url = args.getRevision( name_revision ); revision_file = revision_url; } else { revision_url.kind = svn_opt_revision_head; revision_file.kind = svn_opt_revision_working; } #if defined( PYSVN_HAS_CLIENT_PROPLIST2 ) svn_opt_revision_t peg_revision_url; svn_opt_revision_t peg_revision_file; if( args.hasArg( name_peg_revision ) ) { peg_revision_url = args.getRevision( name_peg_revision ); peg_revision_file = peg_revision_url; } else { peg_revision_url = revision_url; peg_revision_file = revision_file; } #endif Py::List list_of_proplists; for( Py::List::size_type i=0; i<path_list.length(); i++ ) { Py::String path_str( asUtf8String( path_list[i] ) ); std::string path( path_str.as_std_string() ); std::string norm_path( svnNormalisedIfPath( path, pool ) ); svn_opt_revision_t revision; svn_opt_revision_t peg_revision; if( !is_revision_setup ) if( is_svn_url( path ) ) { revision = revision_url; #if defined( PYSVN_HAS_CLIENT_PROPLIST2 ) peg_revision = peg_revision_url; #endif is_url = true; } else { revision = revision_file; #if defined( PYSVN_HAS_CLIENT_PROPLIST2 ) peg_revision = peg_revision_file; #endif } else if( is_svn_url( path ) && !is_url ) { throw Py::AttributeError( "cannot mix URL and PATH in name_path" ); } try { const char *norm_path_c_str= norm_path.c_str(); checkThreadPermission(); PythonAllowThreads permission( m_context ); #if defined( PYSVN_HAS_CLIENT_PROPLIST3 ) ProplistReceiveBaton proplist_baton( &permission, pool, list_of_proplists ); svn_error_t *error = svn_client_proplist3 ( norm_path_c_str, &peg_revision, &revision, depth, changelists, proplist_receiver_c, reinterpret_cast<void *>( &proplist_baton ), m_context, pool ); #elif defined( PYSVN_HAS_CLIENT_PROPLIST2 ) apr_array_header_t *props = NULL; svn_error_t *error = svn_client_proplist2 ( &props, norm_path_c_str, &peg_revision, &revision, recurse, m_context, pool ); #else apr_array_header_t *props = NULL; svn_error_t *error = svn_client_proplist ( &props, norm_path_c_str, &revision, recurse, m_context, pool ); #endif permission.allowThisThread(); if( error != NULL ) throw SvnException( error ); #if !defined( PYSVN_HAS_CLIENT_PROPLIST3 ) proplistToObject( list_of_proplists, props, pool ); #endif } catch( SvnException &e ) { // use callback error over ClientException m_context.checkForError( m_module.client_error ); throw_client_error( e ); } } return list_of_proplists; }
static gpointer properties_thread (gpointer user_data) { struct thread_args *args = user_data; svn_opt_revision_t revision; svn_error_t *err; svn_client_ctx_t *ctx = args->ctx; apr_pool_t *subpool, *pool = args->pool; TshPropertiesDialog *dialog = args->dialog; gchar *path = args->path; gchar *set_key = args->set_key; gchar *set_value = args->set_value; gboolean depth = args->depth; svn_string_t *value; GtkWidget *error; gchar *error_str; #if CHECK_SVN_VERSION_G(1,7) apr_array_header_t *paths; #endif args->set_key = NULL; args->set_value = NULL; subpool = svn_pool_create (pool); if (set_key) { value = set_value?svn_string_create(set_value, subpool):NULL; #if CHECK_SVN_VERSION_G(1,7) paths = apr_array_make (subpool, 1, sizeof (const char *)); APR_ARRAY_PUSH (paths, const char *) = path; if ((err = svn_client_propset_local(set_key, value, paths, depth, FALSE, NULL, ctx, subpool))) #else if ((err = svn_client_propset3(NULL, set_key, value, path, depth, FALSE, SVN_INVALID_REVNUM, NULL, NULL, ctx, subpool))) #endif { error_str = tsh_strerror(err); G_GNUC_BEGIN_IGNORE_DEPRECATIONS gdk_threads_enter(); G_GNUC_END_IGNORE_DEPRECATIONS error = gtk_message_dialog_new(GTK_WINDOW(dialog), GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, _("Set property failed")); gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(error), "%s", error_str); tsh_dialog_start(GTK_DIALOG(error), FALSE); G_GNUC_BEGIN_IGNORE_DEPRECATIONS gdk_threads_leave(); G_GNUC_END_IGNORE_DEPRECATIONS g_free(error_str); svn_error_clear(err); } } g_free (set_key); g_free (set_value); revision.kind = svn_opt_revision_unspecified; #if CHECK_SVN_VERSION_G(1,8) svn_proplist_receiver2_t receiver2; void *receiver2_baton; wrap_proplist_receiver(&receiver2, &receiver2_baton, tsh_proplist_func, dialog, pool); if ((err = svn_client_proplist4(path, &revision, &revision, svn_depth_empty, NULL, FALSE, receiver2, receiver2_baton, ctx, subpool))) #else if ((err = svn_client_proplist3(path, &revision, &revision, svn_depth_empty, NULL, tsh_proplist_func, dialog, ctx, subpool))) #endif { svn_pool_destroy (subpool); error_str = tsh_strerror(err); G_GNUC_BEGIN_IGNORE_DEPRECATIONS gdk_threads_enter(); G_GNUC_END_IGNORE_DEPRECATIONS tsh_properties_dialog_done (dialog); error = gtk_message_dialog_new(GTK_WINDOW(dialog), GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, _("Properties failed")); gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(error), "%s", error_str); tsh_dialog_start(GTK_DIALOG(error), FALSE); G_GNUC_BEGIN_IGNORE_DEPRECATIONS gdk_threads_leave(); G_GNUC_END_IGNORE_DEPRECATIONS g_free(error_str); svn_error_clear(err); tsh_reset_cancel(); return GINT_TO_POINTER (FALSE); } svn_pool_destroy (subpool); G_GNUC_BEGIN_IGNORE_DEPRECATIONS gdk_threads_enter(); tsh_properties_dialog_done (dialog); gdk_threads_leave(); G_GNUC_END_IGNORE_DEPRECATIONS tsh_reset_cancel(); return GINT_TO_POINTER (TRUE); }