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
// | PHP version 5                                                        |
5
// +----------------------------------------------------------------------+
6
// | Copyright (c) 2004-2007, Clay Loveless                               |
7
// | All rights reserved.                                                 |
8
// +----------------------------------------------------------------------+
9
// | This LICENSE is in the BSD license style.                            |
10
// | http://www.opensource.org/licenses/bsd-license.php                   |
11
// |                                                                      |
12
// | Redistribution and use in source and binary forms, with or without   |
13
// | modification, are permitted provided that the following conditions   |
14
// | are met:                                                             |
15
// |                                                                      |
16
// |  * Redistributions of source code must retain the above copyright    |
17
// |    notice, this list of conditions and the following disclaimer.     |
18
// |                                                                      |
19
// |  * Redistributions in binary form must reproduce the above           |
20
// |    copyright notice, this list of conditions and the following       |
21
// |    disclaimer in the documentation and/or other materials provided   |
22
// |    with the distribution.                                            |
23
// |                                                                      |
24
// |  * Neither the name of Clay Loveless nor the names of contributors   |
25
// |    may be used to endorse or promote products derived from this      |
26
// |    software without specific prior written permission.               |
27
// |                                                                      |
28
// | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS  |
29
// | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT    |
30
// | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS    |
31
// | FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE      |
32
// | COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,  |
33
// | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
34
// | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;     |
35
// | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER     |
36
// | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT   |
37
// | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN    |
38
// | ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE      |
39
// | POSSIBILITY OF SUCH DAMAGE.                                          |
40
// +----------------------------------------------------------------------+
41
// | Author: Clay Loveless <clay@killersoft.com>                          |
42
// +----------------------------------------------------------------------+
43
//
44
// $Id: Diff.php 292829 2009-12-30 23:16:56Z mrook $
45
//
46
 
47
/**
48
 * @package     VersionControl_SVN
49
 * @category    VersionControl
50
 * @author      Clay Loveless <clay@killersoft.com>
51
 */
52
 
53
/**
54
 * Subversion Diff command manager class
55
 *
56
 * Display the differences between two paths.
57
 *
58
 * From 'svn diff --help':
59
 *
60
 * usage: 1. diff [-r N[:M]] [--old OLD-TARGET] [--new NEW-TARGET] [PATH...]
61
 *        2. diff -r N:M URL
62
 *        3. diff [-r N[:M]] URL1[@N] URL2[@M]
63
 *
64
 *   1. Display the differences between OLD-TARGET and NEW-TARGET.  PATHs, if
65
 *      given, are relative to OLD-TARGET and NEW-TARGET and restrict the output
66
 *      to differences for those paths.  OLD-TARGET and NEW-TARGET may be working
67
 *      copy paths or URL[@REV].
68
 *
69
 *      OLD-TARGET defaults to the path '.' and NEW-TARGET defaults to OLD-TARGET.
70
 *      N defaults to BASE or, if OLD-TARGET is an URL, to HEAD.
71
 *      M defaults to the current working version or, if NEW-TARGET is an URL,
72
 *      to HEAD.
73
 *
74
 *      '-r N' sets the revision of OLD-TGT to N, '-r N:M' also sets the
75
 *      revision of NEW-TGT to M.
76
 *
77
 *   2. Shorthand for 'svn diff -r N:M --old=URL --new=URL'.
78
 *
79
 *   3. Shorthand for 'svn diff [-r N[:M]] --old=URL1 --new=URL2'
80
 *
81
 *   Use just 'svn diff' to display local modifications in a working copy
82
 *
83
 * Conversion of the above usage examples to VersionControl_SVN_Diff:
84
 *
85
 * Example 1:
86
 * <code>
87
 * <?php
88
 * require_once 'VersionControl/SVN.php';
89
 *
90
 * // Setup error handling -- always a good idea!
91
 * $svnstack = &PEAR_ErrorStack::singleton('VersionControl_SVN');
92
 *
93
 * // Set up runtime options. Will be passed to all
94
 * // subclasses.
95
 * $options = array('fetchmode' => VERSIONCONTROL_SVN_FETCHMODE_RAW);
96
 *
97
 * $switches = array('r' => '5:8');
98
 * $args = array('svn://svn.example.com/repos/TestProj/trunk/example.php',
99
 *               'svn://svn.example.com/repos/TestProj/trunk/example2.php');
100
 * );
101
 *
102
 * $svn = VersionControl_SVN::factory(array('diff'), $options);
103
 * if ($diffs = $svn->diff->run($args, $switches)) {
104
 *     echo "<pre>$diffs</pre>";
105
 * } else {
106
 *     if (count($errs = $svnstack->getErrors())) {
107
 *         foreach ($errs as $err) {
108
 *             echo '<br />'.$err['message']."<br />\n";
109
 *             echo "Command used: " . $err['params']['cmd'];
110
 *         }
111
 *     }
112
 * }
113
 * ?>
114
 * </code>
115
 *
116
 * Example 2:
117
 * <code>
118
 * <?php
119
 * require_once 'VersionControl/SVN.php';
120
 *
121
 * // Setup error handling -- always a good idea!
122
 * $svnstack = &PEAR_ErrorStack::singleton('VersionControl_SVN');
123
 *
124
 * // Set up runtime options. Will be passed to all
125
 * // subclasses.
126
 * $options = array('fetchmode' => VERSIONCONTROL_SVN_FETCHMODE_RAW);
127
 *
128
 * $switches = array('r' => '5:8');
129
 * $args = array('svn://svn.example.com/repos/TestProj/trunk/example.php');
130
 *
131
 * $svn = VersionControl_SVN::factory(array('diff'), $options);
132
 * if ($diffs = $svn->diff->run($args, $switches)) {
133
 *     echo "<pre>$diffs</pre>";
134
 * } else {
135
 *     if (count($errs = $svnstack->getErrors())) {
136
 *         foreach ($errs as $err) {
137
 *             echo '<br />'.$err['message']."<br />\n";
138
 *             echo "Command used: " . $err['params']['cmd'];
139
 *         }
140
 *     }
141
 * }
142
 * ?>
143
 * </code>
144
 *
145
 * Example 3:
146
 * <code>
147
 * <?php
148
 * require_once 'VersionControl/SVN.php';
149
 *
150
 * // Setup error handling -- always a good idea!
151
 * $svnstack = &PEAR_ErrorStack::singleton('VersionControl_SVN');
152
 *
153
 * // Set up runtime options. Will be passed to all
154
 * // subclasses.
155
 * $options = array('fetchmode' => VERSIONCONTROL_SVN_FETCHMODE_RAW);
156
 *
157
 * $switches = array('r' => '5:8');
158
 * $args = array('svn://svn.example.com/repos/TestProj/trunk/example.php',
159
 *               'svn://svn.example.com/repos/TestProj/trunk/example2.php');
160
 *
161
 * $svn = VersionControl_SVN::factory(array('diff'), $options);
162
 * if ($diffs = $svn->diff->run($args, $switches)) {
163
 *     echo "<pre>$diffs</pre>";
164
 * } else {
165
 *     if (count($errs = $svnstack->getErrors())) {
166
 *         foreach ($errs as $err) {
167
 *             echo '<br />'.$err['message']."<br />\n";
168
 *             echo "Command used: " . $err['params']['cmd'];
169
 *         }
170
 *     }
171
 * }
172
 * ?>
173
 * </code>
174
 *
175
 * $switches is an array containing one or more command line options
176
 * defined by the following associative keys:
177
 *
178
 * <code>
179
 *
180
 * $switches = array(
181
 *  'r [revision]'  =>  'ARG (some commands also take ARG1:ARG2 range)
182
 *                        A revision argument can be one of:
183
 *                           NUMBER       revision number
184
 *                           "{" DATE "}" revision at start of the date
185
 *                           "HEAD"       latest in repository
186
 *                           "BASE"       base rev of item's working copy
187
 *                           "COMMITTED"  last commit at or before BASE
188
 *                           "PREV"       revision just before COMMITTED',
189
 *                      // either 'r' or 'revision' may be used
190
 *  'old'           =>  'OLD-TARGET',
191
 *                      // use OLD-TARGET as the older target
192
 *  'new'           =>  'NEW-TARGET',
193
 *                      // use NEW-TARGET as the newer target
194
 *  'x [extensions]'=>  'ARG',
195
 *                      // pass ARG as bundled options to GNU diff
196
 *                      // either 'x' or 'extensions' may be used
197
 *  'N'             =>  true|false,
198
 *                      // operate on single directory only
199
 *  'non-recursive' =>  true|false,
200
 *                      // operate on single directory only
201
 *  'diff-cmd'      =>  'ARG',
202
 *                      // use ARG as diff command
203
 *  'no-diff-deleted' => true|false,
204
 *                      // do not print differences for deleted files
205
 *  'notice-ancestry' => true|false,
206
 *                      // notice ancestry when calculating differences
207
 *  'username'      =>  'Subversion repository login',
208
 *  'password'      =>  'Subversion repository password',
209
 *  'no-auth-cache' =>  true|false,
210
 *                      // Do not cache authentication tokens
211
 *  'config-dir'    =>  'Path to a Subversion configuration directory'
212
 * );
213
 *
214
 * </code>
215
 *
216
 * Note: Subversion does not offer an XML output option for this subcommand
217
 *
218
 * The non-interactive option available on the command-line
219
 * svn client may also be set (true|false), but it is set to true by default.
220
 *
221
 * The editor-cmd option available on the command-line svn client is not available
222
 * since this class does not operate as an interactive shell session.
223
 *
224
 * @package  VersionControl_SVN
225
 * @version  0.3.4
226
 * @category SCM
227
 * @author   Clay Loveless <clay@killersoft.com>
228
 */
229
class VersionControl_SVN_Diff extends VersionControl_SVN
230
{
231
    /**
232
     * Valid switches for svn diff
233
     *
234
     * @var     array
235
     * @access  public
236
     */
237
    var $valid_switches = array('r',
238
                                'revision',
239
                                'old',
240
                                'new',
241
                                'x',
242
                                'extensions',
243
                                'N',
244
                                'non-recursive',
245
                                'non_recursive',
246
                                'diff-cmd',
247
                                'no-diff-deleted',
248
                                'no_diff_deleted',
249
                                'notice-ancestry',
250
                                'notice_ancestry',
251
                                'username',
252
                                'password',
253
                                'no-auth-cache',
254
                                'no_auth_cache',
255
                                'non-interactive',
256
                                'non_interactive',
257
                                'config-dir',
258
                                'config_dir',
259
                                'summarize'
260
                                );
261
 
262
    /**
263
     * Command-line arguments that should be passed
264
     * <b>outside</b> of those specified in {@link switches}.
265
     *
266
     * @var     array
267
     * @access  public
268
     */
269
    var $args = array();
270
 
271
    /**
272
     * Minimum number of args required by this subcommand.
273
     * See {@link http://svnbook.red-bean.com/svnbook/ Version Control with Subversion},
274
     * Subversion Complete Reference for details on arguments for this subcommand.
275
     * @var     int
276
     * @access  public
277
     */
278
    var $min_args = 1;
279
 
280
    /**
281
     * Switches required by this subcommand.
282
     * See {@link http://svnbook.red-bean.com/svnbook/ Version Control with Subversion},
283
     * Subversion Complete Reference for details on arguments for this subcommand.
284
     * @var     array
285
     * @access  public
286
     */
287
    var $required_switches = array();
288
 
289
    /**
290
     * Use exec or passthru to get results from command.
291
     * @var     bool
292
     * @access  public
293
     */
294
    var $passthru = false;
295
 
296
    /**
297
     * Prepare the svn subcommand switches.
298
     *
299
     * Defaults to non-interactive mode, and will auto-set the
300
     * --xml switch (if available) if $fetchmode is set to VERSIONCONTROL_SVN_FETCHMODE_XML,
301
     * VERSIONCONTROL_SVN_FETCHMODE_ASSOC or VERSIONCONTROL_SVN_FETCHMODE_OBJECT
302
     *
303
     * @param   void
304
     * @return  int    true on success, false on failure. Check PEAR_ErrorStack
305
     *                 for error details, if any.
306
     */
307
    function prepare()
308
    {
309
        $meets_requirements = $this->checkCommandRequirements();
310
        if (!$meets_requirements) {
311
            return false;
312
        }
313
 
314
        $valid_switches     = $this->valid_switches;
315
        $switches           = $this->switches;
316
        $args               = $this->args;
317
        $fetchmode          = $this->fetchmode;
318
        $invalid_switches   = array();
319
        $_switches          = '';
320
 
321
        foreach ($switches as $switch => $val) {
322
            if (in_array($switch, $valid_switches)) {
323
                $switch = str_replace('_', '-', $switch);
324
                switch ($switch) {
325
                    case 'revision':
326
                    case 'username':
327
                    case 'password':
328
                    case 'old':
329
                    case 'new':
330
                    case 'extensions':
331
                    case 'diff-cmd':
332
                    case 'config-dir':
333
                        $_switches .= "--$switch $val ";
334
                        break;
335
                    case 'r':
336
                    case 'x':
337
                        $_switches .= "-$switch $val ";
338
                        break;
339
                    case 'F':
340
                    case 'm':
341
                        $_switches .= "-$switch \"$val\" ";
342
                        break;
343
                    case 'no-auth-cache':
344
                    case 'no-diff-deleted':
345
                    case 'notice-ancestry':
346
                    case 'non-interactive':
347
                    case 'non-recursive':
348
                    case 'summarize':
349
                        if ($val === true) {
350
                            $_switches .= "--$switch ";
351
                        }
352
                        break;
353
                    case 'N':
354
                        if ($val === true) {
355
                            $switches .= "-$switch ";
356
                        }
357
                        break;
358
                    default:
359
                        // that's all, folks!
360
                        break;
361
                }
362
            } else {
363
                $invalid_switches[] = $switch;
364
            }
365
        }
366
        // We don't want interactive mode
367
        if (strpos($_switches, 'non-interactive') === false) {
368
            $_switches .= '--non-interactive ';
369
        }
370
        $_switches = trim($_switches);
371
        $this->_switches = $_switches;
372
 
373
        $cmd = "$this->svn_path $this->_svn_cmd $_switches";
374
        if (!empty($args)) {
375
            $cmd .= ' '. join(' ', $args);
376
        }
377
 
378
        $this->_prepped_cmd = $cmd;
379
        $this->prepared = true;
380
 
381
        $invalid = count($invalid_switches);
382
        if ($invalid > 0) {
383
            $params['was'] = 'was';
384
            $params['is_invalid_switch'] = 'is an invalid switch';
385
            if ($invalid > 1) {
386
                $params['was'] = 'were';
387
                $params['is_invalid_switch'] = 'are invalid switches';
388
            }
389
            $params['list'] = $invalid_switches;
390
            $params['switches'] = $switches;
391
            $params['_svn_cmd'] = ucfirst($this->_svn_cmd);
392
            $this->_stack->push(VERSIONCONTROL_SVN_NOTICE_INVALID_SWITCH, 'notice', $params);
393
        }
394
        return true;
395
    }
396
 
397
    // }}}
398
    // {{{ parseOutput()
399
 
400
    /**
401
     * Handles output parsing of standard and verbose output of command.
402
     *
403
     * @param   array   $out    Array of output captured by exec command in {@link run}.
404
     * @return  mixed   Returns output requested by fetchmode (if available), or raw output
405
     *                  if desired fetchmode is not available.
406
     * @access  public
407
     */
408
    function parseOutput($out)
409
    {
410
        $fetchmode = $this->fetchmode;
411
        switch($fetchmode) {
412
            case VERSIONCONTROL_SVN_FETCHMODE_RAW:
413
                return join("\n", $out);
414
                break;
415
            case VERSIONCONTROL_SVN_FETCHMODE_ASSOC:
416
                // Temporary, see parseOutputArray below
417
                return join("\n", $out);
418
                break;
419
            case VERSIONCONTROL_SVN_FETCHMODE_OBJECT:
420
                // Temporary, will return object-ified array from
421
                // parseOutputArray
422
                return join("\n", $out);
423
                break;
424
            case VERSIONCONTROL_SVN_FETCHMODE_XML:
425
                // Temporary, will eventually build an XML string
426
                // with XML_Util or XML_Tree
427
                return join("\n", $out);
428
                break;
429
            default:
430
                // What you get with VERSIONCONTROL_SVN_FETCHMODE_DEFAULT
431
                return join("\n", $out);
432
                break;
433
        }
434
    }
435
 
436
    /**
437
     * Helper method for parseOutput that parses output into an associative array
438
     *
439
     * @todo Finish this method! : )
440
     */
441
    function parseOutputArray($out)
442
    {
443
        $parsed = array();
444
    }
445
}
446
 
447
// }}}
448
?>