Subversion-Projekte lars-tiefland.php_share

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
1 lars 1
<?php
2
/* vim: set expandtab tabstop=4 shiftwidth=4: */
3
 
4
/**
5
 * +----------------------------------------------------------------------+
6
 * | PHP version 5                                                        |
7
 * +----------------------------------------------------------------------+
8
 * | Copyright (c) 2004-2007, Clay Loveless                               |
9
 * | All rights reserved.                                                 |
10
 * +----------------------------------------------------------------------+
11
 * | This LICENSE is in the BSD license style.                            |
12
 * | http://www.opensource.org/licenses/bsd-license.php                   |
13
 * |                                                                      |
14
 * | Redistribution and use in source and binary forms, with or without   |
15
 * | modification, are permitted provided that the following conditions   |
16
 * | are met:                                                             |
17
 * |                                                                      |
18
 * |  * Redistributions of source code must retain the above copyright    |
19
 * |    notice, this list of conditions and the following disclaimer.     |
20
 * |                                                                      |
21
 * |  * Redistributions in binary form must reproduce the above           |
22
 * |    copyright notice, this list of conditions and the following       |
23
 * |    disclaimer in the documentation and/or other materials provided   |
24
 * |    with the distribution.                                            |
25
 * |                                                                      |
26
 * |  * Neither the name of Clay Loveless nor the names of contributors   |
27
 * |    may be used to endorse or promote products derived from this      |
28
 * |    software without specific prior written permission.               |
29
 * |                                                                      |
30
 * | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS  |
31
 * | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT    |
32
 * | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS    |
33
 * | FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE      |
34
 * | COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,  |
35
 * | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
36
 * | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;     |
37
 * | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER     |
38
 * | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT   |
39
 * | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN    |
40
 * | ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE      |
41
 * | POSSIBILITY OF SUCH DAMAGE.                                          |
42
 * +----------------------------------------------------------------------+
43
 *
44
 * @category  VersionControl
45
 * @package   VersionControl_SVN
46
 * @author    Clay Loveless <clay@killersoft.com>
47
 * @author    Michiel Rook <mrook@php.net>
48
 * @copyright 2004-2007 Clay Loveless
49
 * @license   http://www.killersoft.com/LICENSE.txt BSD License
50
 * @version   SVN: $Id: SVN.php 302158 2010-08-12 18:49:10Z mrook $
51
 * @link      http://pear.php.net/package/VersionControl_SVN
52
 */
53
 
54
// {{{ Error Management
55
require_once 'PEAR/ErrorStack.php';
56
 
57
// error & notice constants
58
define('VERSIONCONTROL_SVN_ERROR', -1);
59
define('VERSIONCONTROL_SVN_ERROR_NO_VERSION', -2);
60
define('VERSIONCONTROL_SVN_ERROR_NO_REVISION', -3);
61
define('VERSIONCONTROL_SVN_ERROR_UNKNOWN_CMD', -4);
62
define('VERSIONCONTROL_SVN_ERROR_NOT_IMPLEMENTED', -5);
63
define('VERSIONCONTROL_SVN_ERROR_NO_SWITCHES', -6);
64
define('VERSIONCONTROL_SVN_ERROR_UNDEFINED', -7);
65
define('VERSIONCONTROL_SVN_ERROR_REQUIRED_SWITCH_MISSING', -8);
66
define('VERSIONCONTROL_SVN_ERROR_MIN_ARGS', -9);
67
define('VERSIONCONTROL_SVN_ERROR_EXEC', -10);
68
define('VERSIONCONTROL_SVN_NOTICE', -999);
69
define('VERSIONCONTROL_SVN_NOTICE_INVALID_SWITCH', -901);
70
define('VERSIONCONTROL_SVN_NOTICE_INVALID_OPTION', -902);
71
 
72
// }}}
73
// {{{ fetch modes
74
 
75
/**
76
 * Note on the fetch modes -- as the project matures, more of these modes
77
 * will be implemented. At the time of initial release only the
78
 * Log and List commands implement anything other than basic
79
 * RAW output.
80
 */
81
 
82
/**
83
 * This is a special constant that tells VersionControl_SVN the user hasn't specified
84
 * any particular get mode, so the default should be used.
85
 */
86
define('VERSIONCONTROL_SVN_FETCHMODE_DEFAULT', 0);
87
 
88
/**
89
 * Responses returned in associative array format
90
 */
91
define('VERSIONCONTROL_SVN_FETCHMODE_ASSOC', 1);
92
 
93
/**
94
 * Responses returned as object properties
95
 */
96
define('VERSIONCONTROL_SVN_FETCHMODE_OBJECT', 2);
97
 
98
/**
99
 * Responses returned as raw XML (as passed-thru from svn --xml command responses)
100
 */
101
define('VERSIONCONTROL_SVN_FETCHMODE_XML', 3);
102
 
103
/**
104
 * Responses returned as string - unmodified from command-line output
105
 */
106
define('VERSIONCONTROL_SVN_FETCHMODE_RAW', 4);
107
 
108
/**
109
 * Responses returned as raw output, but all available output parsing methods
110
 * are performed and stored in the {@link output} property.
111
 */
112
define('VERSIONCONTROL_SVN_FETCHMODE_ALL', 5);
113
 
114
/**
115
 * Responses returned as numbered array
116
 */
117
define('VERSIONCONTROL_SVN_FETCHMODE_ARRAY', 6);
118
 
119
// }}}
120
 
121
/**
122
 * Simple OO interface for Subversion
123
 *
124
 * @tutorial  VersionControl_SVN.pkg
125
 * @category  VersionControl
126
 * @package   VersionControl_SVN
127
 * @author    Clay Loveless <clay@killersoft.com>
128
 * @author    Michiel Rook <mrook@php.net>
129
 * @copyright 2004-2007 Clay Loveless
130
 * @license   http://www.killersoft.com/LICENSE.txt BSD License
131
 * @version   0.3.4
132
 * @link      http://pear.php.net/package/VersionControl_SVN
133
 * @static
134
 */
135
class VersionControl_SVN
136
{
137
 
138
    // {{{ Public Properties
139
 
140
    /**
141
     * Reference array of subcommand shortcuts. Provided for convenience for
142
     * those who prefer the shortcuts they're used to using with the svn
143
     * command-line tools.
144
     *
145
     * You may specify your own shortcuts by passing them in to the factory.
146
     * For example:
147
     *
148
     * <code>
149
     * <?php
150
     * require_once 'VersionControl/SVN.php';
151
     *
152
     * $options['shortcuts'] = array('boot' => 'Delete', 'checkin' => 'Commit');
153
     *
154
     * $svn = VersionControl_SVN::factory(array('boot', 'checkin'), $options);
155
     *
156
     * $switches = array('username' => 'user', 'password' => 'pass', 'force' => true);
157
     * $args = array('svn://svn.example.com/repos/TestProject/file_to_delete.txt');
158
     *
159
     * $svn->boot->run($switches, $args);
160
     *
161
     * ?>
162
     * </code>
163
     *
164
     * @var     array
165
     * @access  public
166
     */
167
    var $shortcuts = array(
168
 
169
            'praise'    => 'Blame',
170
            'annotate'  => 'Blame',
171
            'ann'       => 'Blame',
172
            'co'        => 'Checkout',
173
            'ci'        => 'Commit',
174
            'cp'        => 'Copy',
175
            'del'       => 'Delete',
176
            'remove'    => 'Delete',
177
            'rm'        => 'Delete',
178
            'di'        => 'Diff',
179
            'ls'        => 'List',
180
            'mv'        => 'Move',
181
            'rename'    => 'Move',
182
            'ren'       => 'Move',
183
            'pdel'      => 'Propdel',
184
            'pd'        => 'Propdel',
185
            'pget'      => 'Propget',
186
            'pg'        => 'Propget',
187
            'plist'     => 'Proplist',
188
            'pl'        => 'Proplist',
189
            'pset'      => 'Propset',
190
            'ps'        => 'Propset',
191
            'stat'      => 'Status',
192
            'st'        => 'Status',
193
            'sw'        => 'Switch',
194
            'up'        => 'Update'
195
        );
196
 
197
    /**
198
     * Indicates whether commands passed to the {@link http://www.php.net/exec exec()} function in
199
     * the {@link run} method should be passed through
200
     * {@link http://www.php.net/escapeshellcmd escapeshellcmd()}.
201
     * NOTE: this variable is ignored on Windows machines!
202
     *
203
     * @var     bool
204
     * @access  public
205
     */
206
    var $use_escapeshellcmd = true;
207
 
208
    /**
209
     * Location of the svn client binary installed as part of Subversion
210
     *
211
     * @var     string  $svn_path
212
     * @access  public
213
     */
214
    var $svn_path = '/usr/local/bin/svn';
215
 
216
    /**
217
     * String to prepend to command string. Helpful for setting exec()
218
     * environment variables, such as:
219
     *    export LANG=en_US.utf8 &&
220
     * ... to support non-ASCII file and directory names.
221
     *
222
     * @var     string $prepend_cmd
223
     * @access  public
224
     */
225
    var $prepend_cmd = '';
226
 
227
    /**
228
     * Array of switches to use in building svn command
229
     *
230
     * @var     array
231
     * @access  public
232
     */
233
    var $switches = array();
234
 
235
    /**
236
     * Runtime options being used.
237
     *
238
     * @var     array
239
     * @access  public
240
     */
241
    var $options = array();
242
 
243
    /**
244
     * Preferred fetchmode. Note that not all subcommands have output available for
245
     * each preferred fetchmode. The default cascade is:
246
     *
247
     * VERSIONCONTROL_SVN_FETCHMODE_ASSOC
248
     *  VERSIONCONTROL_SVN_FETCHMODE_RAW
249
     *
250
     * If the specified fetchmode isn't available, raw output will be returned.
251
     *
252
     * @var     int
253
     * @access  public
254
     */
255
    var $fetchmode = VERSIONCONTROL_SVN_FETCHMODE_ASSOC;
256
 
257
    /**
258
     * XML::Parser class to use for parsing XML output
259
     *
260
     * @var     string
261
     * @access  public
262
     */
263
    var $svn_cmd_parser;
264
 
265
    // }}}
266
    // {{{ Private Properties
267
 
268
    /**
269
     * SVN subcommand to run.
270
     *
271
     * @var     string
272
     * @access  private
273
     */
274
    var $_svn_cmd = '';
275
 
276
    /**
277
     * Keep track of whether options are prepared or not.
278
     *
279
     * @var     bool
280
     * @access  private
281
     */
282
    var $_prepared = false;
283
 
284
    /**
285
     * Fully prepared command string.
286
     *
287
     * @var     string
288
     * @access  private
289
     */
290
    var $_prepped_cmd = '';
291
 
292
    /**
293
     * Keep track of whether XML output is available for a command
294
     *
295
     * @var     bool
296
     * @access  private
297
     */
298
    var $_xml_avail = false;
299
 
300
    /**
301
     * Error stack.
302
     *
303
     * @var     object
304
     * @access  private
305
     */
306
    var $_stack;
307
 
308
    /**
309
     * Assembled switches for command line execution
310
     *
311
     * @var     object
312
     * @access  private
313
     */
314
    var $_switches = '';
315
 
316
    // }}}
317
    // {{{ errorMessages()
318
 
319
    /**
320
     * Set up VersionControl_SVN error message templates for PEAR_ErrorStack.
321
     *
322
     * @return  array
323
     * @access  public
324
     */
325
    function declareErrorMessages()
326
    {
327
        $messages = array(
328
            VERSIONCONTROL_SVN_ERROR => '%errstr%',
329
            VERSIONCONTROL_SVN_ERROR_EXEC => '%errstr% (cmd: %cmd%)',
330
            VERSIONCONTROL_SVN_ERROR_NO_VERSION =>
331
                'undefined 2',
332
            VERSIONCONTROL_SVN_ERROR_NO_REVISION =>
333
                'undefined 3',
334
            VERSIONCONTROL_SVN_ERROR_UNKNOWN_CMD =>
335
                '\'%command%\' is not a known VersionControl_SVN command.',
336
            VERSIONCONTROL_SVN_ERROR_NOT_IMPLEMENTED =>
337
                '\'%method%\' is not implemented in the %class% class.',
338
            VERSIONCONTROL_SVN_ERROR_NO_SWITCHES =>
339
                'undefined 6',
340
            VERSIONCONTROL_SVN_ERROR_REQUIRED_SWITCH_MISSING =>
341
                'svn %_svn_cmd% requires the following %switchstr%: %missing%',
342
            VERSIONCONTROL_SVN_ERROR_MIN_ARGS =>
343
                'svn %_svn_cmd% requires at least %min_args% %argstr%',
344
            VERSIONCONTROL_SVN_NOTICE => '%notice%',
345
            VERSIONCONTROL_SVN_NOTICE_INVALID_SWITCH =>
346
                '\'%list%\' %is_invalid_switch% for VersionControl_SVN_%_svn_cmd% and %was% ignored. ' .
347
                    'Please refer to the documentation.',
348
            VERSIONCONTROL_SVN_NOTICE_INVALID_OPTION =>
349
                '\'%option%\' is not a valid option, and was ignored.'
350
        );
351
 
352
        return $messages;
353
    }
354
 
355
    // {{{ factory()
356
 
357
    /**
358
     * Create a new VersionControl_SVN command object.
359
     *
360
     * $options is an array containing multiple options
361
     * defined by the following associative keys:
362
     *
363
     * <code>
364
     *
365
     * array(
366
     *  'url'           => 'Subversion repository URL',
367
     *  'username'      => 'Subversion repository login',
368
     *  'password'      => 'Subversion repository password',
369
     *  'config_dir'    => 'Path to a Subversion configuration directory',
370
     *                     // [DEFAULT: null]
371
     *  'dry_run'       => true/false,
372
     *                     // [DEFAULT: false]
373
     *  'encoding'      => 'Language encoding to use for commit messages',
374
     *                     // [DEFAULT: null]
375
     *  'svn_path'      => 'Path to the svn client binary installed as part of Subversion',
376
     *                     // [DEFAULT: /usr/local/bin/svn]
377
     * )
378
     *
379
     * </code>
380
     *
381
     * Example 1.
382
     * <code>
383
     * <?php
384
     * require_once 'VersionControl/SVN.php';
385
     *
386
     * $options = array(
387
     *      'url'        => 'https://www.example.com/repos',
388
     *      'path'       => 'your_project',
389
     *      'username'   => 'your_login',
390
     *      'password'   => 'your_password',
391
     * );
392
     *
393
     * // Run a log command
394
     * $svn = VersionControl_SVN::factory('log', $options);
395
     *
396
     * print_r($svn->run());
397
     * ?>
398
     * </code>
399
     *
400
     * @param string $command The Subversion command
401
     * @param array  $options An associative array of option names and
402
     *                        their values
403
     *
404
     * @return  mixed   a newly created VersionControl_SVN command object, or PEAR_ErrorStack
405
     *                  constant on error
406
     *
407
     * @access  public
408
     */
409
    function &factory($command, $options = array())
410
    {
411
        $stack = &PEAR_ErrorStack::singleton('VersionControl_SVN');
412
        $stack->setErrorMessageTemplate(VersionControl_SVN::declareErrorMessages());
413
        if (is_string($command) && strtoupper($command) == '__ALL__') {
414
            unset($command);
415
            $command = array();
416
            $command = VersionControl_SVN::fetchCommands();
417
        }
418
        if (is_array($command)) {
419
            $objects = new stdClass;
420
            foreach ($command as $cmd) {
421
                $obj = VersionControl_SVN::init($cmd, $options);
422
                $objects->$cmd = $obj;
423
            }
424
            return $objects;
425
        } else {
426
            $obj = VersionControl_SVN::init($command, $options);
427
            return $obj;
428
        }
429
    }
430
 
431
    // }}}
432
    // {{{ init()
433
 
434
    /**
435
     * Initialize an object wrapper for a Subversion subcommand.
436
     *
437
     * @param string $command The Subversion command
438
     * @param array  $options An associative array of option names and
439
     *                        their values
440
     *
441
     * @return  mixed   object on success, false on failure
442
     * @access public
443
     */
444
    function init($command, $options)
445
    {
446
        // Check for shortcuts for commands
447
        $shortcuts = VersionControl_SVN::fetchShortcuts();
448
        if (isset($options['shortcuts']) && is_array($options['shortcuts'])) {
449
            foreach ($options['shortcuts'] as $key => $val) {
450
                $shortcuts[strtolower($key)] = $val;
451
            }
452
        }
453
        $cmd = isset($shortcuts[strtolower($command)]) ? $shortcuts[strtolower($command)] : $command;
454
        $lowercmd   = strtolower($cmd);
455
        $cmd        = ucfirst($lowercmd);
456
        $class      = 'VersionControl_SVN_'.$cmd;
457
        if (include_once realpath(dirname(__FILE__)) . "/SVN/{$cmd}.php") {
458
            if (class_exists($class)) {
459
                $obj =& new $class;
460
                $obj->options   = $options;
461
                $obj->_svn_cmd  = $lowercmd;
462
                $obj->_stack    = &PEAR_ErrorStack::singleton('VersionControl_SVN');
463
                $obj->_stack->setErrorMessageTemplate(VersionControl_SVN::declareErrorMessages());
464
                $obj->setOptions($options);
465
                return $obj;
466
            }
467
        }
468
        PEAR_ErrorStack::staticPush('VersionControl_SVN', VERSIONCONTROL_SVN_ERROR_UNKNOWN_CMD, 'error',
469
            array('command' => $command, 'options' => $options));
470
        return false;
471
    }
472
 
473
    // }}}
474
    // {{{ fetchCommands()
475
 
476
    /**
477
     * Scan through the SVN directory looking for subclasses.
478
     *
479
     * @return  mixed    array on success, false on failure
480
     * @access  public
481
     */
482
    function fetchCommands()
483
    {
484
        $commands = array();
485
        $dir = realpath(dirname(__FILE__)) . '/SVN';
486
        $dp = @opendir($dir);
487
        if (empty($dp)) {
488
            PEAR_ErrorStack::staticPush('VersionControl_SVN', VERSIONCONTROL_SVN_ERROR, 'error',
489
                array('errstr' => "fetchCommands: opendir($dir) failed"));
490
            return false;
491
        }
492
        while ($entry = readdir($dp)) {
493
            if ($entry{0} == '.' || substr($entry, -4) != '.php') {
494
                continue;
495
            }
496
            $commands[] = substr($entry, 0, -4);
497
        }
498
        closedir($dp);
499
        return $commands;
500
    }
501
 
502
    // }}}
503
    // {{{ fetchShortcuts()
504
 
505
    /**
506
     * Return the array of pre-defined shortcuts (also known as Alternate Names)
507
     * for Subversion commands.
508
     *
509
     * @return  array
510
     * @access public
511
     */
512
    function fetchShortcuts()
513
    {
514
        $vars = get_class_vars('VersionControl_SVN');
515
        return $vars['shortcuts'];
516
    }
517
 
518
    // }}}
519
    // {{{ setOptions()
520
 
521
    /**
522
     * Allow for overriding of previously declared options.
523
     *
524
     * @param array $options An associative array of option names and
525
     *                       their values
526
     *
527
     * @return boolean
528
     */
529
    function setOptions($options = array())
530
    {
531
        $opts = array_filter(array_keys(get_class_vars('VersionControl_SVN')), array($this, '_filterOpts'));
532
        foreach ($options as $option => $value) {
533
            if (in_array($option, $opts)) {
534
                if ($option == 'shortcuts') {
535
                    $this->shortcuts = array_merge($this->shortcuts, $value);
536
                } else {
537
                    $this->$option = $value;
538
                }
539
            } else {
540
                $this->_stack->push(VERSIONCONTROL_SVN_NOTICE_INVALID_OPTION, 'notice',
541
                    array('option' => $option));
542
            }
543
        }
544
        return true;
545
    }
546
 
547
    // }}}
548
    // {{{ prepare()
549
 
550
    /**
551
     * Prepare the command switches.
552
     *
553
     * This function should be overloaded by the command class.
554
     *
555
     * @return boolean
556
     */
557
    function prepare()
558
    {
559
        $this->_stack->push(VERSIONCONTROL_SVN_ERROR_NOT_IMPLEMENTED, 'error',
560
            array('options' => $this->options, 'method' => 'prepare()', 'class' => get_class($this)));
561
        return false;
562
    }
563
 
564
    // }}}
565
    // {{{ checkCommandRequirements()
566
 
567
    /**
568
     * Standardized validation of requirements for a command class.
569
     *
570
     * @return mixed   true if all requirements are met, false if
571
     *                  requirements are not met. Details of failures
572
     *                  are pushed into the PEAR_ErrorStack for VersionControl_SVN
573
     * @access  public
574
     */
575
    function checkCommandRequirements()
576
    {
577
        // Set up error push parameters to avoid any notices about undefined indexes
578
        $params['options']  = $this->options;
579
        $params['switches'] = $this->switches;
580
        $params['args']     = $this->args;
581
        $params['_svn_cmd'] = $this->_svn_cmd;
582
        $params['cmd']      = '';
583
 
584
        // Check for minimum arguments
585
        if (sizeof($this->args) < $this->min_args) {
586
            $params['argstr'] = $this->min_args > 1 ? 'arguments' : 'argument';
587
            $params['min_args'] = $this->min_args;
588
            $this->_stack->push(VERSIONCONTROL_SVN_ERROR_MIN_ARGS, 'error', $params);
589
            return false;
590
        }
591
 
592
        // Check for presence of required switches
593
        if (sizeof($this->required_switches) > 0) {
594
            $missing    = array();
595
            $switches   = $this->switches;
596
            $reqsw      = $this->required_switches;
597
            foreach ($reqsw as $req) {
598
                $found = false;
599
                $good_switches = explode('|', $req);
600
                foreach ($good_switches as $gsw) {
601
                    if (isset($switches[$gsw])) {
602
                        $found = true;
603
                    }
604
                }
605
                if (!$found) {
606
                    $missing[] = '('.$req.')';
607
                }
608
            }
609
            $num_missing = count($missing);
610
            if ($num_missing > 0) {
611
                $params['switchstr'] = $num_missing > 1 ? 'switches' : 'switch';
612
                $params['missing'] = $missing;
613
                $this->_stack->push(VERSIONCONTROL_SVN_ERROR_REQUIRED_SWITCH_MISSING, 'error', $params);
614
                return false;
615
            }
616
        }
617
        return true;
618
    }
619
 
620
    // }}}
621
    // {{{ run()
622
 
623
    /**
624
     * Run the command with the defined switches.
625
     *
626
     * @param array $args     Arguments to pass to Subversion
627
     * @param array $switches Switches to pass to Subversion
628
     *
629
     * @return  mixed   $fetchmode specified output on success,
630
     *                  or false on failure.
631
     * @access  public
632
     */
633
    function run($args = array(), $switches = array())
634
    {
635
        if (sizeof($switches) > 0) {
636
            $this->switches = $switches;
637
        }
638
        if (sizeof($args) > 0) {
639
            foreach (array_keys($args) as $k) {
640
                $this->args[$k] = escapeshellarg($args[$k]);
641
            }
642
        }
643
 
644
        // Always prepare, allows for obj re-use. (Request #5021)
645
        $this->prepare();
646
 
647
        $out        = array();
648
        $ret_var    = null;
649
 
650
        $cmd = $this->_prepped_cmd;
651
 
652
        // On Windows, don't use escapeshellcmd, and double-quote $cmd so it's
653
        // executed as 'cmd /c ""C:\Program Files\SVN\bin\svn.exe" info "C:\Program Files\dev\trunk""
654
        if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN')
655
        {
656
            $cmd = str_replace($this->svn_path, escapeshellarg($this->svn_path), $cmd);
657
 
658
            if (!$this->passthru) {
659
                exec("$cmd 2>&1", $out, $ret_var);
660
            } else {
661
                passthru("$cmd 2>&1", $ret_var);
662
            }
663
        }
664
        else
665
        {
666
            if ($this->use_escapeshellcmd) {
667
                $cmd = escapeshellcmd($cmd);
668
            }
669
 
670
            if (!$this->passthru) {
671
                exec("{$this->prepend_cmd}$cmd 2>&1", $out, $ret_var);
672
            } else {
673
                passthru("{$this->prepend_cmd}$cmd 2>&1", $ret_var);
674
            }
675
        }
676
 
677
        if ($ret_var > 0) {
678
            $params['options']  = $this->options;
679
            $params['switches'] = $this->switches;
680
            $params['args']     = $this->args;
681
            $params['cmd']      = $cmd;
682
            foreach ($out as $line) {
683
                $params['errstr'] = $line;
684
                $this->_stack->push(VERSIONCONTROL_SVN_ERROR_EXEC, 'error', $params);
685
            }
686
            return false;
687
        }
688
        return $this->parseOutput($out);
689
    }
690
 
691
    // }}}
692
    // {{{ parseOutput()
693
 
694
    /**
695
     * Handle output parsing chores.
696
     *
697
     * This bare-bones function should be overridden by the command class.
698
     *
699
     * @param array $out Array of output captured by exec command in {@link run}
700
     *
701
     * @return  mixed   Returns output requested by fetchmode (if available), or
702
     *                  raw output if desired fetchmode is not available.
703
     * @access  public
704
     */
705
    function parseOutput($out)
706
    {
707
        return join("\n", $out);
708
    }
709
 
710
    // }}}
711
    // {{{ apiVersion()
712
 
713
    /**
714
     * Return the VersionControl_SVN API version
715
     *
716
     * @return  string  the VersionControl_SVN API version number
717
     *
718
     * @access  public
719
     */
720
    function apiVersion()
721
    {
722
        return '0.3.4';
723
    }
724
 
725
    // }}}
726
    // {{{ _filterOpts
727
 
728
    /**
729
     * Callback function for array_filter. Keeps _private options
730
     * out of settable options.
731
     *
732
     * @param string $var Passed value
733
     *
734
     * @return boolean
735
     */
736
    function _filterOpts($var)
737
    {
738
        $ret = ($var{0} == '_') ? false : true;
739
        return $ret;
740
    }
741
    // }}}
742
}
743
 
744
// }}}
745
?>