1<?php
2
3/*
4 * This file is part of Composer.
5 *
6 * (c) Nils Adermann <naderman@naderman.de>
7 *     Jordi Boggiano <j.boggiano@seld.be>
8 *
9 * For the full copyright and license information, please view the LICENSE
10 * file that was distributed with this source code.
11 */
12
13namespace Composer\Repository\Vcs;
14
15use Composer\Config;
16use Composer\IO\IOInterface;
17use Composer\Util\ProcessExecutor;
18use Composer\Util\Perforce;
19
20/**
21 * @author Matt Whittom <Matt.Whittom@veteransunited.com>
22 */
23class PerforceDriver extends VcsDriver
24{
25    protected $depot;
26    protected $branch;
27    protected $perforce;
28    protected $composerInfo;
29    protected $composerInfoIdentifier;
30
31    /**
32     * {@inheritDoc}
33     */
34    public function initialize()
35    {
36        $this->depot = $this->repoConfig['depot'];
37        $this->branch = '';
38        if (!empty($this->repoConfig['branch'])) {
39            $this->branch = $this->repoConfig['branch'];
40        }
41
42        $this->initPerforce($this->repoConfig);
43        $this->perforce->p4Login($this->io);
44        $this->perforce->checkStream($this->depot);
45
46        $this->perforce->writeP4ClientSpec();
47        $this->perforce->connectClient();
48
49        return true;
50    }
51
52    private function initPerforce($repoConfig)
53    {
54        if (!empty($this->perforce)) {
55            return;
56        }
57
58        $repoDir = $this->config->get('cache-vcs-dir') . '/' . $this->depot;
59        $this->perforce = Perforce::create($repoConfig, $this->getUrl(), $repoDir, $this->process, $this->io);
60    }
61
62    /**
63     * {@inheritDoc}
64     */
65    public function getComposerInformation($identifier)
66    {
67        if (!empty($this->composerInfoIdentifier)) {
68            if (strcmp($identifier, $this->composerInfoIdentifier) === 0) {
69                return $this->composerInfo;
70            }
71        }
72        $composer_info = $this->perforce->getComposerInformation($identifier);
73
74        return $composer_info;
75    }
76
77    /**
78     * {@inheritDoc}
79     */
80    public function getRootIdentifier()
81    {
82        return $this->branch;
83    }
84
85    /**
86     * {@inheritDoc}
87     */
88    public function getBranches()
89    {
90        $branches = $this->perforce->getBranches();
91
92        return $branches;
93    }
94
95    /**
96     * {@inheritDoc}
97     */
98    public function getTags()
99    {
100        $tags = $this->perforce->getTags();
101
102        return $tags;
103    }
104
105    /**
106     * {@inheritDoc}
107     */
108    public function getDist($identifier)
109    {
110        return null;
111    }
112
113    /**
114     * {@inheritDoc}
115     */
116    public function getSource($identifier)
117    {
118        $source = array(
119            'type'      => 'perforce',
120            'url'       => $this->repoConfig['url'],
121            'reference' => $identifier,
122            'p4user'    => $this->perforce->getUser(),
123        );
124
125        return $source;
126    }
127
128    /**
129     * {@inheritDoc}
130     */
131    public function getUrl()
132    {
133        return $this->url;
134    }
135
136    /**
137     * {@inheritDoc}
138     */
139    public function hasComposerFile($identifier)
140    {
141        $this->composerInfo = $this->perforce->getComposerInformation('//' . $this->depot . '/' . $identifier);
142        $this->composerInfoIdentifier = $identifier;
143
144        return !empty($this->composerInfo);
145    }
146
147    /**
148     * {@inheritDoc}
149     */
150    public function getContents($url)
151    {
152        return false;
153    }
154
155    /**
156     * {@inheritDoc}
157     */
158    public static function supports(IOInterface $io, Config $config, $url, $deep = false)
159    {
160        if ($deep || preg_match('#\b(perforce|p4)\b#i', $url)) {
161            return Perforce::checkServerExists($url, new ProcessExecutor($io));
162        }
163
164        return false;
165    }
166
167    /**
168     * {@inheritDoc}
169     */
170    public function cleanup()
171    {
172        $this->perforce->cleanupClientSpec();
173        $this->perforce = null;
174    }
175
176    public function getDepot()
177    {
178        return $this->depot;
179    }
180
181    public function getBranch()
182    {
183        return $this->branch;
184    }
185}
186