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