1 //
2 // ====================================================================
3 // Copyright (c) 2003-2009 Barry A Scott.  All rights reserved.
4 //
5 // This software is licensed as described in the file LICENSE.txt,
6 // which you should have received as part of this distribution.
7 //
8 // ====================================================================
9 //
10 //
11 //  pysvn_client_cmd_export.cpp
12 //
13 #if defined( _MSC_VER )
14 // disable warning C4786: symbol greater than 255 character,
15 // nessesary to ignore as <map> causes lots of warning
16 #pragma warning(disable: 4786)
17 #endif
18 
19 #include "pysvn.hpp"
20 #include "pysvn_static_strings.hpp"
21 
22 static const char *g_utf_8 = "utf-8";
23 
cmd_export(const Py::Tuple & a_args,const Py::Dict & a_kws)24 Py::Object pysvn_client::cmd_export( const Py::Tuple &a_args, const Py::Dict &a_kws )
25 {
26     static argument_description args_desc[] =
27     {
28     { true,  name_src_url_or_path },
29     { true,  name_dest_path },
30     { false, name_force },
31     { false, name_revision },
32 #if defined( PYSVN_HAS_CLIENT_EXPORT2 )
33     { false, name_native_eol },
34 #endif
35 #if defined( PYSVN_HAS_CLIENT_EXPORT3 )
36     { false, name_ignore_externals },
37     { false, name_recurse },
38     { false, name_peg_revision },
39 #endif
40 #if defined( PYSVN_HAS_CLIENT_EXPORT4 )
41     { false, name_depth },
42 #endif
43 #if defined( PYSVN_HAS_CLIENT_EXPORT5 )
44     { false, name_ignore_keywords },
45 #endif
46     { false, NULL }
47     };
48     FunctionArguments args( "export", args_desc, a_args, a_kws );
49     args.check();
50 
51     std::string src_path( args.getUtf8String( name_src_url_or_path ) );
52     std::string dest_path( args.getUtf8String( name_dest_path ) );
53     bool is_url = is_svn_url( src_path );
54 
55     bool force = args.getBoolean( name_force, false );
56     svn_opt_revision_t revision;
57     if( is_url )
58          revision = args.getRevision( name_revision, svn_opt_revision_head );
59     else
60          revision = args.getRevision( name_revision, svn_opt_revision_working );
61 
62 #if defined( PYSVN_HAS_CLIENT_EXPORT2 )
63     const char *native_eol = NULL;
64     if( args.hasArg( name_native_eol ) )
65     {
66         Py::Object native_eol_obj = args.getArg( name_native_eol );
67         if( native_eol_obj != Py::None() )
68         {
69             Py::String eol_py_str( native_eol_obj );
70             std::string eol_str = eol_py_str.as_std_string( g_utf_8 );
71             if( eol_str == "CR" )
72                 native_eol = "CR";
73             else if( eol_str == "CRLF" )
74                 native_eol = "CRLF";
75             else if( eol_str == "LF" )
76                 native_eol = "LF";
77             else
78                 throw Py::ValueError( "native_eol must be one of None, \"LF\", \"CRLF\" or \"CR\"" );
79         }
80     }
81 #endif
82 #if defined( PYSVN_HAS_CLIENT_EXPORT3 )
83 #if defined( PYSVN_HAS_CLIENT_EXPORT4 )
84     svn_depth_t depth = args.getDepth( name_depth, name_recurse, svn_depth_infinity, svn_depth_infinity, svn_depth_files );
85 #else
86     bool recurse = args.getBoolean( name_recurse, true );
87 #endif
88     bool ignore_externals = args.getBoolean( name_ignore_externals, false );
89     svn_opt_revision_t peg_revision = args.getRevision( name_peg_revision, revision );
90 
91     revisionKindCompatibleCheck( is_url, peg_revision, name_peg_revision, name_url_or_path );
92 #endif
93 
94 #if defined( PYSVN_HAS_CLIENT_EXPORT5 )
95     bool ignore_keywords = args.getBoolean( name_ignore_keywords, false );
96 #endif
97 
98     revisionKindCompatibleCheck( is_url, revision, name_revision, name_url_or_path );
99 
100     svn_revnum_t revnum = 0;
101 
102     SvnPool pool( m_context );
103 
104     try
105     {
106         std::string norm_src_path( svnNormalisedIfPath( src_path, pool ) );
107         std::string norm_dest_path( svnNormalisedIfPath( dest_path, pool ) );
108 
109         checkThreadPermission();
110 
111         PythonAllowThreads permission( m_context );
112 
113 #if defined( PYSVN_HAS_CLIENT_EXPORT5 )
114         svn_error_t * error = svn_client_export5
115             (
116             &revnum,
117             norm_src_path.c_str(),
118             norm_dest_path.c_str(),
119             &peg_revision,
120             &revision,
121             force,
122             ignore_externals,
123             ignore_keywords,
124             depth,
125             native_eol,
126             m_context,
127             pool
128             );
129 #elif defined( PYSVN_HAS_CLIENT_EXPORT4 )
130         svn_error_t * error = svn_client_export4
131             (
132             &revnum,
133             norm_src_path.c_str(),
134             dest_path.c_str(),
135             &peg_revision,
136             &revision,
137             force,
138             ignore_externals,
139             depth,
140             native_eol,
141             m_context,
142             pool
143             );
144 #elif defined( PYSVN_HAS_CLIENT_EXPORT3 )
145         svn_error_t * error = svn_client_export3
146             (
147             &revnum,
148             norm_src_path.c_str(),
149             dest_path.c_str(),
150             &peg_revision,
151             &revision,
152             force,
153             ignore_externals,
154             recurse,
155             native_eol,
156             m_context,
157             pool
158             );
159 #elif defined( PYSVN_HAS_CLIENT_EXPORT2 )
160         svn_error_t * error = svn_client_export2
161             (
162             &revnum,
163             norm_src_path.c_str(),
164             dest_path.c_str(),
165             &revision,
166             force,
167             native_eol,
168             m_context,
169             pool
170             );
171 #else
172         svn_error_t * error = svn_client_export
173             (
174             &revnum,
175             norm_src_path.c_str(),
176             dest_path.c_str(),
177             &revision,
178             force,
179             m_context,
180             pool
181             );
182 #endif
183         permission.allowThisThread();
184         if( error != NULL )
185             throw SvnException( error );
186     }
187     catch( SvnException &e )
188     {
189         // use callback error over ClientException
190         m_context.checkForError( m_module.client_error );
191 
192         throw_client_error( e );
193     }
194 
195     return Py::asObject( new pysvn_revision( svn_opt_revision_number, 0, revnum ) );
196 }
197 
cmd_import(const Py::Tuple & a_args,const Py::Dict & a_kws)198 Py::Object pysvn_client::cmd_import( const Py::Tuple &a_args, const Py::Dict &a_kws )
199 {
200     static argument_description args_desc[] =
201     {
202     { true,  name_path },
203     { true,  name_url },
204     { true,  name_log_message },
205     { false, name_recurse },
206 #if defined( PYSVN_HAS_CLIENT_IMPORT2 )
207     { false, name_ignore },
208 #endif
209 #if defined( PYSVN_HAS_CLIENT_IMPORT3 )
210     { false, name_depth },
211     { false, name_ignore_unknown_node_types },
212     { false, name_revprops },
213 #endif
214 #if defined( PYSVN_HAS_CLIENT_IMPORT5 )
215     { false, name_autoprops },
216 #endif
217     { false, NULL }
218     };
219     FunctionArguments args( "import_", args_desc, a_args, a_kws );
220     args.check();
221 
222     std::string path( args.getUtf8String( name_path ) );
223     std::string url( args.getUtf8String( name_url ) );
224     std::string message( args.getUtf8String( name_log_message ) );
225 
226     SvnPool pool( m_context );
227 
228 #if defined( PYSVN_HAS_CLIENT_IMPORT3 )
229     svn_depth_t depth = args.getDepth( name_depth, name_recurse, svn_depth_infinity, svn_depth_infinity, svn_depth_files );
230     bool ignore_unknown_node_types = args.getBoolean( name_ignore_unknown_node_types, false );
231 
232     apr_hash_t *revprops = NULL;
233     if( args.hasArg( name_revprops ) )
234     {
235         Py::Object py_revprop = args.getArg( name_revprops );
236         if( !py_revprop.isNone() )
237         {
238             revprops = hashOfStringsFromDictOfStrings( py_revprop, pool );
239         }
240     }
241 #else
242     bool recurse = args.getBoolean( name_recurse, true );
243 #endif
244 #if defined( PYSVN_HAS_CLIENT_IMPORT2 )
245     bool ignore = args.getBoolean( name_ignore, false );
246 #endif
247 
248 #if defined( PYSVN_HAS_CLIENT_IMPORT5 )
249     bool autoprops = args.getBoolean( name_autoprops, true );
250 #endif
251 
252 #if defined( PYSVN_HAS_CLIENT_IMPORT4 )
253     CommitInfoResult commit_info( pool );
254 #else
255     pysvn_commit_info_t *commit_info = NULL;
256 #endif
257 
258     try
259     {
260         std::string norm_path( svnNormalisedIfPath( path, pool ) );
261         std::string norm_url( svnNormalisedUrl( url, pool ) );
262 
263         checkThreadPermission();
264 
265         PythonAllowThreads permission( m_context );
266 
267         m_context.setLogMessage( message.c_str() );
268 
269 #if defined( PYSVN_HAS_CLIENT_IMPORT5 )
270         svn_error_t *error = svn_client_import5
271             (
272             norm_path.c_str(),
273             norm_url.c_str(),
274             depth,
275             !ignore,
276             !autoprops,
277             ignore_unknown_node_types,
278             revprops,
279             NULL,       // filter_callback
280             NULL,       // filter_baton
281             commit_info.callback(),
282             commit_info.baton(),
283             m_context,
284             pool
285             );
286 #elif defined( PYSVN_HAS_CLIENT_IMPORT4 )
287         svn_error_t *error = svn_client_import4
288             (
289             norm_path.c_str(),
290             norm_url.c_str(),
291             depth,
292             !ignore,
293             ignore_unknown_node_types,
294             revprops,
295             commit_info.callback(),
296             commit_info.baton(),
297             m_context,
298             pool
299             );
300 #elif defined( PYSVN_HAS_CLIENT_IMPORT3 )
301         svn_error_t *error = svn_client_import3
302             (
303             &commit_info,       // changed type
304             norm_path.c_str(),
305             norm_url.c_str(),
306             depth,
307             !ignore,
308             ignore_unknown_node_types,
309             revprops,
310             m_context,
311             pool
312             );
313 #elif defined( PYSVN_HAS_CLIENT_IMPORT2 )
314         svn_error_t *error = svn_client_import2
315             (
316             &commit_info,       // changed type
317             norm_path.c_str(),
318             url.c_str(),
319             !recurse,           // non_recursive
320             !ignore,
321             m_context,
322             pool
323             );
324 #else
325         svn_error_t *error = svn_client_import
326             (
327             &commit_info,
328             norm_path.c_str(),
329             url.c_str(),
330             !recurse,           // non_recursive
331             m_context,
332             pool
333             );
334 #endif
335         permission.allowThisThread();
336         if( error != NULL )
337             throw SvnException( error );
338     }
339     catch( SvnException &e )
340     {
341         // use callback error over ClientException
342         m_context.checkForError( m_module.client_error );
343 
344         throw_client_error( e );
345     }
346 
347 #if defined( PYSVN_HAS_CLIENT_IMPORT4 )
348     return toObject( commit_info, m_wrapper_commit_info, m_commit_info_style );
349 #else
350     return toObject( commit_info, m_commit_info_style );
351 #endif
352 }
353