1: <?php
2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13:
14: class Horde_Vcs_Patchset_Cvs extends Horde_Vcs_Patchset_Base
15: {
16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30:
31: public function __construct($rep, $opts = array())
32: {
33: $file = $rep->sourceroot . '/' . $opts['file'];
34:
35:
36: if (!$rep->isFile($file)) {
37: throw new Horde_Vcs_Exception('File Not Found');
38: }
39:
40:
41: $cvsps_home = $rep->getPath('cvsps_home');
42: $HOME = !empty($cvsps_home) ?
43: 'HOME=' . escapeshellarg($cvsps_home) . ' ' :
44: '';
45:
46: $rangecmd = empty($opts['range'])
47: ? ''
48: : ' -s ' . escapeshellarg(implode(',', $opts['range']));
49:
50: $ret_array = array();
51: $cmd = $HOME . escapeshellcmd($rep->getPath('cvsps')) . $rangecmd
52: . ' -u --cvs-direct --root ' . escapeshellarg($rep->sourceroot)
53: . ' -f ' . escapeshellarg(basename($file))
54: . ' -q ' . escapeshellarg(dirname($file));
55: exec($cmd, $ret_array, $retval);
56: if ($retval) {
57: throw new Horde_Vcs_Exception('Failed to spawn cvsps to retrieve patchset information.');
58: }
59:
60: $state = 'begin';
61: reset($ret_array);
62: while (list(,$line) = each($ret_array)) {
63: $line = trim($line);
64:
65: if ($line == '---------------------') {
66: $state = 'begin';
67: continue;
68: }
69:
70: switch ($state) {
71: case 'begin':
72: $id = str_replace('PatchSet ', '', $line);
73: $this->_patchsets[$id] = array('revision' => $id);
74: $state = 'info';
75: break;
76:
77: case 'info':
78: $info = explode(':', $line, 2);
79: $info[1] = ltrim($info[1]);
80:
81: switch ($info[0]) {
82: case 'Date':
83: $d = new DateTime($info[1]);
84: $this->_patchsets[$id]['date'] = $d->format('U');
85: break;
86:
87: case 'Author':
88: $this->_patchsets[$id]['author'] = $info[1];
89: break;
90:
91: case 'Branch':
92: $this->_patchsets[$id]['branches'] = ($info[1] == 'HEAD')
93: ? array()
94: : array($info[1]);
95: break;
96:
97: case 'Tag':
98: $this->_patchsets[$id]['tags'] = ($info[1] == '(none)')
99: ? array()
100: : array($info[1]);
101: break;
102:
103: case 'Log':
104: $state = 'log';
105: $this->_patchsets[$id]['log'] = '';
106: break;
107: }
108: break;
109:
110: case 'log':
111: if ($line == 'Members:') {
112: $state = 'members';
113: $this->_patchsets[$id]['log'] = rtrim($this->_patchsets[$id]['log']);
114: $this->_patchsets[$id]['members'] = array();
115: } else {
116: $this->_patchsets[$id]['log'] .= $line . "\n";
117: }
118: break;
119:
120: case 'members':
121: if (!empty($line)) {
122: $parts = explode(':', $line);
123: list($from, $to) = explode('->', $parts[1], 2);
124: $status = Horde_Vcs_Patchset::MODIFIED;
125:
126: if ($from == 'INITIAL') {
127: $from = null;
128: $status = Horde_Vcs_Patchset::ADDED;
129: } elseif (substr($to, -6) == '(DEAD)') {
130: $to = null;
131: $status = Horde_Vcs_Patchset::DELETED;
132: }
133:
134: $this->_patchsets[$id]['members'][] = array(
135: 'file' => $parts[0],
136: 'from' => $from,
137: 'status' => $status,
138: 'to' => $to
139: );
140: }
141: break;
142: }
143: }
144: }
145: }