Py::Object pysvn_client::cmd_export( const Py::Tuple &a_args, const Py::Dict &a_kws ) { static argument_description args_desc[] = { { true, name_src_url_or_path }, { true, name_dest_path }, { false, name_force }, { false, name_revision }, #if defined( PYSVN_HAS_CLIENT_EXPORT2 ) { false, name_native_eol }, #endif #if defined( PYSVN_HAS_CLIENT_EXPORT3 ) { false, name_ignore_externals }, { false, name_recurse }, { false, name_peg_revision }, #endif #if defined( PYSVN_HAS_CLIENT_EXPORT4 ) { false, name_depth }, #endif { false, NULL } }; FunctionArguments args( "export", args_desc, a_args, a_kws ); args.check(); std::string src_path( args.getUtf8String( name_src_url_or_path ) ); std::string dest_path( args.getUtf8String( name_dest_path ) ); bool is_url = is_svn_url( src_path ); bool force = args.getBoolean( name_force, false ); svn_opt_revision_t revision; if( is_url ) revision = args.getRevision( name_revision, svn_opt_revision_head ); else revision = args.getRevision( name_revision, svn_opt_revision_working ); #if defined( PYSVN_HAS_CLIENT_EXPORT2 ) const char *native_eol = NULL; if( args.hasArg( name_native_eol ) ) { Py::Object native_eol_obj = args.getArg( name_native_eol ); if( native_eol_obj != Py::None() ) { Py::String eol_py_str( native_eol_obj ); std::string eol_str = eol_py_str.as_std_string( g_utf_8 ); if( eol_str == "CR" ) native_eol = "CR"; else if( eol_str == "CRLF" ) native_eol = "CRLF"; else if( eol_str == "LF" ) native_eol = "LF"; else throw Py::ValueError( "native_eol must be one of None, \"LF\", \"CRLF\" or \"CR\"" ); } } #endif #if defined( PYSVN_HAS_CLIENT_EXPORT3 ) #if defined( PYSVN_HAS_CLIENT_EXPORT4 ) svn_depth_t depth = args.getDepth( name_depth, name_recurse, svn_depth_infinity, svn_depth_infinity, svn_depth_files ); #else bool recurse = args.getBoolean( name_recurse, true ); #endif bool ignore_externals = args.getBoolean( name_ignore_externals, false ); svn_opt_revision_t peg_revision = args.getRevision( name_peg_revision, revision ); revisionKindCompatibleCheck( is_url, peg_revision, name_peg_revision, name_url_or_path ); #endif revisionKindCompatibleCheck( is_url, revision, name_revision, name_url_or_path ); svn_revnum_t revnum = 0; SvnPool pool( m_context ); try { std::string norm_src_path( svnNormalisedIfPath( src_path, pool ) ); checkThreadPermission(); PythonAllowThreads permission( m_context ); #if defined( PYSVN_HAS_CLIENT_EXPORT4 ) svn_error_t * error = svn_client_export4 ( &revnum, norm_src_path.c_str(), dest_path.c_str(), &peg_revision, &revision, force, ignore_externals, depth, native_eol, m_context, pool ); #elif defined( PYSVN_HAS_CLIENT_EXPORT3 ) svn_error_t * error = svn_client_export3 ( &revnum, norm_src_path.c_str(), dest_path.c_str(), &peg_revision, &revision, force, ignore_externals, recurse, native_eol, m_context, pool ); #elif defined( PYSVN_HAS_CLIENT_EXPORT2 ) svn_error_t * error = svn_client_export2 ( &revnum, norm_src_path.c_str(), dest_path.c_str(), &revision, force, native_eol, m_context, pool ); #else svn_error_t * error = svn_client_export ( &revnum, norm_src_path.c_str(), dest_path.c_str(), &revision, force, m_context, pool ); #endif permission.allowThisThread(); if( error != NULL ) throw SvnException( error ); } catch( SvnException &e ) { // use callback error over ClientException m_context.checkForError( m_module.client_error ); throw_client_error( e ); } return Py::asObject( new pysvn_revision( svn_opt_revision_number, 0, revnum ) ); }
/* This implements the `svn_opt_subcommand_t' interface. */ svn_error_t * svn_cl__export(apr_getopt_t *os, void *baton, apr_pool_t *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; const char *from, *to; apr_array_header_t *targets; svn_error_t *err; svn_opt_revision_t peg_revision; const char *truefrom; SVN_ERR(svn_cl__args_to_target_array_print_reserved(&targets, os, opt_state->targets, ctx, pool)); /* We want exactly 1 or 2 targets for this subcommand. */ if (targets->nelts < 1) return svn_error_create(SVN_ERR_CL_INSUFFICIENT_ARGS, 0, NULL); if (targets->nelts > 2) return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, 0, NULL); /* The first target is the `from' path. */ from = APR_ARRAY_IDX(targets, 0, const char *); /* Get the peg revision if present. */ SVN_ERR(svn_opt_parse_path(&peg_revision, &truefrom, from, pool)); /* If only one target was given, split off the basename to use as the `to' path. Else, a `to' path was supplied. */ if (targets->nelts == 1) to = svn_path_uri_decode(svn_path_basename(truefrom, pool), pool); else to = APR_ARRAY_IDX(targets, 1, const char *); SVN_ERR(svn_opt__split_arg_at_peg_revision(&to, NULL, to, pool)); if (! opt_state->quiet) svn_cl__get_notifier(&ctx->notify_func2, &ctx->notify_baton2, FALSE, TRUE, FALSE, pool); if (opt_state->depth == svn_depth_unknown) opt_state->depth = svn_depth_infinity; /* Decode the partially encoded URL and escape all URL unsafe characters. */ if (svn_path_is_url(truefrom)) truefrom = svn_path_uri_encode(svn_path_uri_decode(truefrom, pool), pool); /* Do the export. */ err = svn_client_export4(NULL, truefrom, to, &peg_revision, &(opt_state->start_revision), opt_state->force, opt_state->ignore_externals, opt_state->depth, opt_state->native_eol, ctx, pool); if (err && err->apr_err == SVN_ERR_WC_OBSTRUCTED_UPDATE && !opt_state->force) SVN_ERR_W(err, _("Destination directory exists; please remove " "the directory or use --force to overwrite")); return err; }