123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723 |
- <?php
- /*
- * This file is part of Composer.
- *
- * (c) Nils Adermann <naderman@naderman.de>
- * Jordi Boggiano <j.boggiano@seld.be>
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
- namespace Composer\Test\Util;
- use Composer\Util\Perforce;
- use Composer\Test\TestCase;
- use Composer\Util\ProcessExecutor;
- /**
- * @author Matt Whittom <Matt.Whittom@veteransunited.com>
- */
- class PerforceTest extends TestCase
- {
- protected $perforce;
- protected $processExecutor;
- protected $repoConfig;
- protected $io;
- const TEST_DEPOT = 'depot';
- const TEST_BRANCH = 'branch';
- const TEST_P4USER = 'user';
- const TEST_CLIENT_NAME = 'TEST';
- const TEST_PORT = 'port';
- const TEST_PATH = 'path';
- protected function setUp()
- {
- $this->processExecutor = $this->getMockBuilder('Composer\Util\ProcessExecutor')->getMock();
- $this->repoConfig = $this->getTestRepoConfig();
- $this->io = $this->getMockIOInterface();
- $this->createNewPerforceWithWindowsFlag(true);
- }
- protected function tearDown()
- {
- $this->perforce = null;
- $this->io = null;
- $this->repoConfig = null;
- $this->processExecutor = null;
- }
- public function getTestRepoConfig()
- {
- return array(
- 'depot' => self::TEST_DEPOT,
- 'branch' => self::TEST_BRANCH,
- 'p4user' => self::TEST_P4USER,
- 'unique_perforce_client_name' => self::TEST_CLIENT_NAME,
- );
- }
- public function getMockIOInterface()
- {
- return $this->getMockBuilder('Composer\IO\IOInterface')->getMock();
- }
- protected function createNewPerforceWithWindowsFlag($flag)
- {
- $this->perforce = new Perforce($this->repoConfig, self::TEST_PORT, self::TEST_PATH, $this->processExecutor, $flag, $this->io);
- }
- public function testGetClientWithoutStream()
- {
- $client = $this->perforce->getClient();
- $hostname = gethostname();
- $timestamp = time();
- $expected = 'composer_perforce_TEST_depot';
- $this->assertEquals($expected, $client);
- }
- public function testGetClientFromStream()
- {
- $this->setPerforceToStream();
- $client = $this->perforce->getClient();
- $expected = 'composer_perforce_TEST_depot_branch';
- $this->assertEquals($expected, $client);
- }
- public function testGetStreamWithoutStream()
- {
- $stream = $this->perforce->getStream();
- $this->assertEquals("//depot", $stream);
- }
- public function testGetStreamWithStream()
- {
- $this->setPerforceToStream();
- $stream = $this->perforce->getStream();
- $this->assertEquals('//depot/branch', $stream);
- }
- public function testGetStreamWithoutLabelWithStreamWithoutLabel()
- {
- $stream = $this->perforce->getStreamWithoutLabel('//depot/branch');
- $this->assertEquals('//depot/branch', $stream);
- }
- public function testGetStreamWithoutLabelWithStreamWithLabel()
- {
- $stream = $this->perforce->getStreamWithoutLabel('//depot/branching@label');
- $this->assertEquals('//depot/branching', $stream);
- }
- public function testGetClientSpec()
- {
- $clientSpec = $this->perforce->getP4ClientSpec();
- $expected = 'path/composer_perforce_TEST_depot.p4.spec';
- $this->assertEquals($expected, $clientSpec);
- }
- public function testGenerateP4Command()
- {
- $command = 'do something';
- $p4Command = $this->perforce->generateP4Command($command);
- $expected = 'p4 -u user -c composer_perforce_TEST_depot -p port do something';
- $this->assertEquals($expected, $p4Command);
- }
- public function testQueryP4UserWithUserAlreadySet()
- {
- $this->perforce->queryP4user();
- $this->assertEquals(self::TEST_P4USER, $this->perforce->getUser());
- }
- public function testQueryP4UserWithUserSetInP4VariablesWithWindowsOS()
- {
- $this->createNewPerforceWithWindowsFlag(true);
- $this->perforce->setUser(null);
- $expectedCommand = 'p4 set';
- $callback = function ($command, &$output) {
- $output = 'P4USER=TEST_P4VARIABLE_USER' . PHP_EOL;
- return true;
- };
- $this->processExecutor->expects($this->at(0))
- ->method('execute')
- ->with($this->equalTo($expectedCommand))
- ->will($this->returnCallback($callback));
- $this->perforce->queryP4user();
- $this->assertEquals('TEST_P4VARIABLE_USER', $this->perforce->getUser());
- }
- public function testQueryP4UserWithUserSetInP4VariablesNotWindowsOS()
- {
- $this->createNewPerforceWithWindowsFlag(false);
- $this->perforce->setUser(null);
- $expectedCommand = 'echo $P4USER';
- $callback = function ($command, &$output) {
- $output = 'TEST_P4VARIABLE_USER' . PHP_EOL;
- return true;
- };
- $this->processExecutor->expects($this->at(0))
- ->method('execute')
- ->with($this->equalTo($expectedCommand))
- ->will($this->returnCallback($callback));
- $this->perforce->queryP4user();
- $this->assertEquals('TEST_P4VARIABLE_USER', $this->perforce->getUser());
- }
- public function testQueryP4UserQueriesForUser()
- {
- $this->perforce->setUser(null);
- $expectedQuestion = 'Enter P4 User:';
- $this->io->expects($this->at(0))
- ->method('ask')
- ->with($this->equalTo($expectedQuestion))
- ->will($this->returnValue('TEST_QUERY_USER'));
- $this->perforce->queryP4user();
- $this->assertEquals('TEST_QUERY_USER', $this->perforce->getUser());
- }
- public function testQueryP4UserStoresResponseToQueryForUserWithWindows()
- {
- $this->createNewPerforceWithWindowsFlag(true);
- $this->perforce->setUser(null);
- $expectedQuestion = 'Enter P4 User:';
- $expectedCommand = 'p4 set P4USER=TEST_QUERY_USER';
- $this->io->expects($this->at(0))
- ->method('ask')
- ->with($this->equalTo($expectedQuestion))
- ->will($this->returnValue('TEST_QUERY_USER'));
- $this->processExecutor->expects($this->at(1))
- ->method('execute')
- ->with($this->equalTo($expectedCommand))
- ->will($this->returnValue(0));
- $this->perforce->queryP4user();
- }
- public function testQueryP4UserStoresResponseToQueryForUserWithoutWindows()
- {
- $this->createNewPerforceWithWindowsFlag(false);
- $this->perforce->setUser(null);
- $expectedQuestion = 'Enter P4 User:';
- $expectedCommand = 'export P4USER=TEST_QUERY_USER';
- $this->io->expects($this->at(0))
- ->method('ask')
- ->with($this->equalTo($expectedQuestion))
- ->will($this->returnValue('TEST_QUERY_USER'));
- $this->processExecutor->expects($this->at(1))
- ->method('execute')
- ->with($this->equalTo($expectedCommand))
- ->will($this->returnValue(0));
- $this->perforce->queryP4user();
- }
- public function testQueryP4PasswordWithPasswordAlreadySet()
- {
- $repoConfig = array(
- 'depot' => 'depot',
- 'branch' => 'branch',
- 'p4user' => 'user',
- 'p4password' => 'TEST_PASSWORD',
- );
- $this->perforce = new Perforce($repoConfig, 'port', 'path', $this->processExecutor, false, $this->getMockIOInterface());
- $password = $this->perforce->queryP4Password();
- $this->assertEquals('TEST_PASSWORD', $password);
- }
- public function testQueryP4PasswordWithPasswordSetInP4VariablesWithWindowsOS()
- {
- $this->createNewPerforceWithWindowsFlag(true);
- $expectedCommand = 'p4 set';
- $callback = function ($command, &$output) {
- $output = 'P4PASSWD=TEST_P4VARIABLE_PASSWORD' . PHP_EOL;
- return true;
- };
- $this->processExecutor->expects($this->at(0))
- ->method('execute')
- ->with($this->equalTo($expectedCommand))
- ->will($this->returnCallback($callback));
- $password = $this->perforce->queryP4Password();
- $this->assertEquals('TEST_P4VARIABLE_PASSWORD', $password);
- }
- public function testQueryP4PasswordWithPasswordSetInP4VariablesNotWindowsOS()
- {
- $this->createNewPerforceWithWindowsFlag(false);
- $expectedCommand = 'echo $P4PASSWD';
- $callback = function ($command, &$output) {
- $output = 'TEST_P4VARIABLE_PASSWORD' . PHP_EOL;
- return true;
- };
- $this->processExecutor->expects($this->at(0))
- ->method('execute')
- ->with($this->equalTo($expectedCommand))
- ->will($this->returnCallback($callback));
- $password = $this->perforce->queryP4Password();
- $this->assertEquals('TEST_P4VARIABLE_PASSWORD', $password);
- }
- public function testQueryP4PasswordQueriesForPassword()
- {
- $expectedQuestion = 'Enter password for Perforce user user: ';
- $this->io->expects($this->at(0))
- ->method('askAndHideAnswer')
- ->with($this->equalTo($expectedQuestion))
- ->will($this->returnValue('TEST_QUERY_PASSWORD'));
- $password = $this->perforce->queryP4Password();
- $this->assertEquals('TEST_QUERY_PASSWORD', $password);
- }
- public function testWriteP4ClientSpecWithoutStream()
- {
- $stream = fopen('php://memory', 'w+');
- $this->perforce->writeClientSpecToFile($stream);
- rewind($stream);
- $expectedArray = $this->getExpectedClientSpec(false);
- try {
- foreach ($expectedArray as $expected) {
- $this->assertStringStartsWith($expected, fgets($stream));
- }
- $this->assertFalse(fgets($stream));
- } catch (\Exception $e) {
- fclose($stream);
- throw $e;
- }
- fclose($stream);
- }
- public function testWriteP4ClientSpecWithStream()
- {
- $this->setPerforceToStream();
- $stream = fopen('php://memory', 'w+');
- $this->perforce->writeClientSpecToFile($stream);
- rewind($stream);
- $expectedArray = $this->getExpectedClientSpec(true);
- try {
- foreach ($expectedArray as $expected) {
- $this->assertStringStartsWith($expected, fgets($stream));
- }
- $this->assertFalse(fgets($stream));
- } catch (\Exception $e) {
- fclose($stream);
- throw $e;
- }
- fclose($stream);
- }
- public function testIsLoggedIn()
- {
- $expectedCommand = 'p4 -u user -p port login -s';
- $this->processExecutor->expects($this->at(0))
- ->method('execute')
- ->with($this->equalTo($expectedCommand), $this->equalTo(null))
- ->will($this->returnValue(0));
- $this->perforce->isLoggedIn();
- }
- public function testConnectClient()
- {
- $expectedCommand = 'p4 -u user -c composer_perforce_TEST_depot -p port client -i < path/composer_perforce_TEST_depot.p4.spec';
- $this->processExecutor->expects($this->at(0))
- ->method('execute')
- ->with($this->equalTo($expectedCommand), $this->equalTo(null))
- ->will($this->returnValue(0));
- $this->perforce->connectClient();
- }
- public function testGetBranchesWithStream()
- {
- $this->setPerforceToStream();
- $expectedCommand = 'p4 -u user -c composer_perforce_TEST_depot_branch -p port streams '.ProcessExecutor::escape('//depot/...');
- $this->processExecutor->expects($this->at(0))
- ->method('execute')
- ->with($this->equalTo($expectedCommand))
- ->will(
- $this->returnCallback(
- function ($command, &$output) {
- $output = 'Stream //depot/branch mainline none \'branch\'' . PHP_EOL;
- return true;
- }
- )
- );
- $expectedCommand2 = 'p4 -u user -p port changes '.ProcessExecutor::escape('//depot/branch/...');
- $expectedCallback = function ($command, &$output) {
- $output = 'Change 1234 on 2014/03/19 by Clark.Stuth@Clark.Stuth_test_client \'test changelist\'';
- return true;
- };
- $this->processExecutor->expects($this->at(1))
- ->method('execute')
- ->with($this->equalTo($expectedCommand2))
- ->will($this->returnCallback($expectedCallback));
- $branches = $this->perforce->getBranches();
- $this->assertEquals('//depot/branch@1234', $branches['master']);
- }
- public function testGetBranchesWithoutStream()
- {
- $expectedCommand = 'p4 -u user -p port changes '.ProcessExecutor::escape('//depot/...');
- $expectedCallback = function ($command, &$output) {
- $output = 'Change 5678 on 2014/03/19 by Clark.Stuth@Clark.Stuth_test_client \'test changelist\'';
- return true;
- };
- $this->processExecutor->expects($this->once())
- ->method('execute')
- ->with($this->equalTo($expectedCommand))
- ->will($this->returnCallback($expectedCallback));
- $branches = $this->perforce->getBranches();
- $this->assertEquals('//depot@5678', $branches['master']);
- }
- public function testGetTagsWithoutStream()
- {
- $expectedCommand = 'p4 -u user -c composer_perforce_TEST_depot -p port labels';
- $this->processExecutor->expects($this->at(0))
- ->method('execute')
- ->with($this->equalTo($expectedCommand))
- ->will(
- $this->returnCallback(
- function ($command, &$output) {
- $output = 'Label 0.0.1 2013/07/31 \'First Label!\'' . PHP_EOL . 'Label 0.0.2 2013/08/01 \'Second Label!\'' . PHP_EOL;
- return true;
- }
- )
- );
- $tags = $this->perforce->getTags();
- $this->assertEquals('//depot@0.0.1', $tags['0.0.1']);
- $this->assertEquals('//depot@0.0.2', $tags['0.0.2']);
- }
- public function testGetTagsWithStream()
- {
- $this->setPerforceToStream();
- $expectedCommand = 'p4 -u user -c composer_perforce_TEST_depot_branch -p port labels';
- $this->processExecutor->expects($this->at(0))
- ->method('execute')
- ->with($this->equalTo($expectedCommand))
- ->will(
- $this->returnCallback(
- function ($command, &$output) {
- $output = 'Label 0.0.1 2013/07/31 \'First Label!\'' . PHP_EOL . 'Label 0.0.2 2013/08/01 \'Second Label!\'' . PHP_EOL;
- return true;
- }
- )
- );
- $tags = $this->perforce->getTags();
- $this->assertEquals('//depot/branch@0.0.1', $tags['0.0.1']);
- $this->assertEquals('//depot/branch@0.0.2', $tags['0.0.2']);
- }
- public function testCheckStreamWithoutStream()
- {
- $result = $this->perforce->checkStream('depot');
- $this->assertFalse($result);
- $this->assertFalse($this->perforce->isStream());
- }
- public function testCheckStreamWithStream()
- {
- $this->processExecutor->expects($this->any())->method('execute')
- ->will(
- $this->returnCallback(
- function ($command, &$output) {
- $output = 'Depot depot 2013/06/25 stream /p4/1/depots/depot/... \'Created by Me\'';
- return true;
- }
- )
- );
- $result = $this->perforce->checkStream('depot');
- $this->assertTrue($result);
- $this->assertTrue($this->perforce->isStream());
- }
- public function testGetComposerInformationWithoutLabelWithoutStream()
- {
- $expectedCommand = 'p4 -u user -c composer_perforce_TEST_depot -p port print '.ProcessExecutor::escape('//depot/composer.json');
- $this->processExecutor->expects($this->at(0))
- ->method('execute')
- ->with($this->equalTo($expectedCommand))
- ->will(
- $this->returnCallback(
- function ($command, &$output) {
- $output = PerforceTest::getComposerJson();
- return true;
- }
- )
- );
- $result = $this->perforce->getComposerInformation('//depot');
- $expected = array(
- 'name' => 'test/perforce',
- 'description' => 'Basic project for testing',
- 'minimum-stability' => 'dev',
- 'autoload' => array('psr-0' => array()),
- );
- $this->assertEquals($expected, $result);
- }
- public function testGetComposerInformationWithLabelWithoutStream()
- {
- $expectedCommand = 'p4 -u user -p port files '.ProcessExecutor::escape('//depot/composer.json@0.0.1');
- $this->processExecutor->expects($this->at(0))
- ->method('execute')
- ->with($this->equalTo($expectedCommand))
- ->will(
- $this->returnCallback(
- function ($command, &$output) {
- $output = '//depot/composer.json#1 - branch change 10001 (text)';
- return true;
- }
- )
- );
- $expectedCommand = 'p4 -u user -c composer_perforce_TEST_depot -p port print '.ProcessExecutor::escape('//depot/composer.json@10001');
- $this->processExecutor->expects($this->at(1))
- ->method('execute')
- ->with($this->equalTo($expectedCommand))
- ->will(
- $this->returnCallback(
- function ($command, &$output) {
- $output = PerforceTest::getComposerJson();
- return true;
- }
- )
- );
- $result = $this->perforce->getComposerInformation('//depot@0.0.1');
- $expected = array(
- 'name' => 'test/perforce',
- 'description' => 'Basic project for testing',
- 'minimum-stability' => 'dev',
- 'autoload' => array('psr-0' => array()),
- );
- $this->assertEquals($expected, $result);
- }
- public function testGetComposerInformationWithoutLabelWithStream()
- {
- $this->setPerforceToStream();
- $expectedCommand = 'p4 -u user -c composer_perforce_TEST_depot_branch -p port print '.ProcessExecutor::escape('//depot/branch/composer.json');
- $this->processExecutor->expects($this->at(0))
- ->method('execute')
- ->with($this->equalTo($expectedCommand))
- ->will(
- $this->returnCallback(
- function ($command, &$output) {
- $output = PerforceTest::getComposerJson();
- return true;
- }
- )
- );
- $result = $this->perforce->getComposerInformation('//depot/branch');
- $expected = array(
- 'name' => 'test/perforce',
- 'description' => 'Basic project for testing',
- 'minimum-stability' => 'dev',
- 'autoload' => array('psr-0' => array()),
- );
- $this->assertEquals($expected, $result);
- }
- public function testGetComposerInformationWithLabelWithStream()
- {
- $this->setPerforceToStream();
- $expectedCommand = 'p4 -u user -p port files '.ProcessExecutor::escape('//depot/branch/composer.json@0.0.1');
- $this->processExecutor->expects($this->at(0))
- ->method('execute')
- ->with($this->equalTo($expectedCommand))
- ->will(
- $this->returnCallback(
- function ($command, &$output) {
- $output = '//depot/composer.json#1 - branch change 10001 (text)';
- return true;
- }
- )
- );
- $expectedCommand = 'p4 -u user -c composer_perforce_TEST_depot_branch -p port print '.ProcessExecutor::escape('//depot/branch/composer.json@10001');
- $this->processExecutor->expects($this->at(1))
- ->method('execute')
- ->with($this->equalTo($expectedCommand))
- ->will(
- $this->returnCallback(
- function ($command, &$output) {
- $output = PerforceTest::getComposerJson();
- return true;
- }
- )
- );
- $result = $this->perforce->getComposerInformation('//depot/branch@0.0.1');
- $expected = array(
- 'name' => 'test/perforce',
- 'description' => 'Basic project for testing',
- 'minimum-stability' => 'dev',
- 'autoload' => array('psr-0' => array()),
- );
- $this->assertEquals($expected, $result);
- }
- public function testSyncCodeBaseWithoutStream()
- {
- $expectedCommand = 'p4 -u user -c composer_perforce_TEST_depot -p port sync -f @label';
- $this->processExecutor->expects($this->at(0))
- ->method('execute')
- ->with($this->equalTo($expectedCommand), $this->equalTo(null))
- ->will($this->returnValue(0));
- $this->perforce->syncCodeBase('label');
- }
- public function testSyncCodeBaseWithStream()
- {
- $this->setPerforceToStream();
- $expectedCommand = 'p4 -u user -c composer_perforce_TEST_depot_branch -p port sync -f @label';
- $this->processExecutor->expects($this->at(0))
- ->method('execute')
- ->with($this->equalTo($expectedCommand))
- ->will($this->returnValue(0));
- $this->perforce->syncCodeBase('label');
- }
- public function testCheckServerExists()
- {
- $processExecutor = $this->getMockBuilder('Composer\Util\ProcessExecutor')->getMock();
- $expectedCommand = 'p4 -p '.ProcessExecutor::escape('perforce.does.exist:port').' info -s';
- $processExecutor->expects($this->at(0))
- ->method('execute')
- ->with($this->equalTo($expectedCommand), $this->equalTo(null))
- ->will($this->returnValue(0));
- $result = $this->perforce->checkServerExists('perforce.does.exist:port', $processExecutor);
- $this->assertTrue($result);
- }
- /**
- * Test if "p4" command is missing.
- *
- * @covers \Composer\Util\Perforce::checkServerExists
- *
- * @return void
- */
- public function testCheckServerClientError()
- {
- $processExecutor = $this->getMockBuilder('Composer\Util\ProcessExecutor')->getMock();
- $expectedCommand = 'p4 -p '.ProcessExecutor::escape('perforce.does.exist:port').' info -s';
- $processExecutor->expects($this->at(0))
- ->method('execute')
- ->with($this->equalTo($expectedCommand), $this->equalTo(null))
- ->will($this->returnValue(127));
- $result = $this->perforce->checkServerExists('perforce.does.exist:port', $processExecutor);
- $this->assertFalse($result);
- }
- public static function getComposerJson()
- {
- $composer_json = array(
- '{',
- '"name": "test/perforce",',
- '"description": "Basic project for testing",',
- '"minimum-stability": "dev",',
- '"autoload": {',
- '"psr-0" : {',
- '}',
- '}',
- '}',
- );
- return implode($composer_json);
- }
- private function getExpectedClientSpec($withStream)
- {
- $expectedArray = array(
- 'Client: composer_perforce_TEST_depot',
- PHP_EOL,
- 'Update:',
- PHP_EOL,
- 'Access:',
- 'Owner: user',
- PHP_EOL,
- 'Description:',
- ' Created by user from composer.',
- PHP_EOL,
- 'Root: path',
- PHP_EOL,
- 'Options: noallwrite noclobber nocompress unlocked modtime rmdir',
- PHP_EOL,
- 'SubmitOptions: revertunchanged',
- PHP_EOL,
- 'LineEnd: local',
- PHP_EOL,
- );
- if ($withStream) {
- $expectedArray[] = 'Stream:';
- $expectedArray[] = ' //depot/branch';
- } else {
- $expectedArray[] = 'View: //depot/... //composer_perforce_TEST_depot/...';
- }
- return $expectedArray;
- }
- private function setPerforceToStream()
- {
- $this->perforce->setStream('//depot/branch');
- }
- public function testCleanupClientSpecShouldDeleteClient()
- {
- $fs = $this->getMockBuilder('Composer\Util\Filesystem')->getMock();
- $this->perforce->setFilesystem($fs);
- $testClient = $this->perforce->getClient();
- $expectedCommand = 'p4 -u ' . self::TEST_P4USER . ' -p ' . self::TEST_PORT . ' client -d ' . ProcessExecutor::escape($testClient);
- $this->processExecutor->expects($this->once())->method('execute')->with($this->equalTo($expectedCommand));
- $fs->expects($this->once())->method('remove')->with($this->perforce->getP4ClientSpec());
- $this->perforce->cleanupClientSpec();
- }
- }
|