1
0
Fork 0

Updated Perforce driver to use labels

dev checkin, lots of cleanup to do
pull/2184/merge^2
matt-whittom 2013-07-31 11:01:18 -05:00 committed by mwhittom
parent 36dd7dfea5
commit 64bda65e11
3 changed files with 254 additions and 59 deletions

View File

@ -20,18 +20,19 @@ use Composer\Util\Perforce;
*/ */
class PerforceDownloader extends VcsDownloader class PerforceDownloader extends VcsDownloader
{ {
private $hasStashedChanges = false;
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
public function doDownload(PackageInterface $package, $path) public function doDownload(PackageInterface $package, $path)
{ {
$ref = $package->getSourceReference(); $ref = $package->getSourceReference();
$label = $package->getPrettyVersion();
print ("PerforceDownloader: doDownload: ref:$ref, label:$label\n");
$perforce = new Perforce($ref, $package->getSourceUrl(), $path); $perforce = new Perforce("", "", $package->getSourceUrl(), $path);
$perforce->setStream($ref);
$perforce->writeP4ClientSpec(); $perforce->writeP4ClientSpec();
$perforce->syncCodeBase(); $perforce->syncCodeBase($label);
} }
/** /**

View File

@ -24,8 +24,8 @@ use Composer\Util\Perforce;
*/ */
class PerforceDriver extends VcsDriver class PerforceDriver extends VcsDriver
{ {
protected $rootIdentifier;
protected $depot; protected $depot;
protected $branch;
protected $perforce; protected $perforce;
/** /**
@ -34,16 +34,20 @@ class PerforceDriver extends VcsDriver
public function initialize() public function initialize()
{ {
print ("\nPerforceDriver:initialize\n"); print ("\nPerforceDriver:initialize\n");
$this->rootIdentifier = "mainline";
$this->depot = $this->repoConfig['depot']; $this->depot = $this->repoConfig['depot'];
$this->branch = "";
if (isset($this->repoConfig['branch'])){
$this->branch = $this->repoConfig['branch'];
}
$stream = "//$this->depot/$this->rootIdentifier";
$repoDir = $this->config->get('cache-vcs-dir') . "/$this->depot"; $repoDir = $this->config->get('cache-vcs-dir') . "/$this->depot";
$this->perforce = new Perforce($stream, $this->getUrl(), $repoDir); $this->perforce = new Perforce($this->depot, $this->branch, $this->getUrl(), $repoDir);
$this->perforce->p4Login($this->io); $this->perforce->p4Login($this->io);
$this->perforce->writeP4ClientSpec(); $this->perforce->checkStream($this->depot);
$this->perforce->syncCodeBase();
// $this->perforce->writeP4ClientSpec();
// $this->perforce->syncCodeBase();
return true; return true;
} }
@ -56,7 +60,7 @@ class PerforceDriver extends VcsDriver
*/ */
public function getComposerInformation($identifier) public function getComposerInformation($identifier)
{ {
print ("PerforceDriver:getComposerInformation - identifier: $identifier\n"); print("PerforceDriver:getComposerInformation - identifier: $identifier\n");
$composer_info =$this->perforce->getComposerInformation($identifier); $composer_info =$this->perforce->getComposerInformation($identifier);
return $composer_info; return $composer_info;
} }
@ -67,7 +71,7 @@ class PerforceDriver extends VcsDriver
public function getRootIdentifier() public function getRootIdentifier()
{ {
print ("PerforceDriver:getRootIdentifier\n"); print ("PerforceDriver:getRootIdentifier\n");
return $this->rootIdentifier; return $this->branch;
} }
/** /**
@ -76,19 +80,7 @@ class PerforceDriver extends VcsDriver
public function getBranches() public function getBranches()
{ {
print ("PerforceDriver:getBranches\n"); print ("PerforceDriver:getBranches\n");
$command = "p4 streams //$this->depot/..."; $branches = $this->perforce->getBranches();
$result = shell_exec($command);
$resArray = explode("\n", $result);
$branches = array();
foreach ($resArray as $line){
$resBits = explode(" ", $line);
if (count($resBits) > 4){
$branch = substr($resBits[4], 1, strlen($resBits[4])-2);
$branches[$branch] = $resBits[1];
}
}
$branches['master'] = $branches['mainline'];
return $branches; return $branches;
} }
@ -98,7 +90,8 @@ class PerforceDriver extends VcsDriver
public function getTags() public function getTags()
{ {
print ("PerforceDriver:getTags\n"); print ("PerforceDriver:getTags\n");
return array(); $tags = $this->perforce->getTags();
return $tags;
} }
/** /**
@ -106,7 +99,6 @@ class PerforceDriver extends VcsDriver
*/ */
public function getDist($identifier) public function getDist($identifier)
{ {
print("\nPerforceDriver:getDist: identifier: $identifier\n");
return null; return null;
} }
@ -115,8 +107,6 @@ class PerforceDriver extends VcsDriver
*/ */
public function getSource($identifier) public function getSource($identifier)
{ {
print ("\nPerforceDriver:getSource - identifier: $identifier\n");
$source = array ( $source = array (
'type' => 'perforce', 'type' => 'perforce',
'url' => $this->repoConfig['url'], 'url' => $this->repoConfig['url'],

View File

@ -20,9 +20,12 @@ class Perforce {
protected $p4port; protected $p4port;
protected $p4stream; protected $p4stream;
protected $p4clientSpec; protected $p4clientSpec;
protected $p4depotType;
protected $p4branch;
final public function __construct($stream, $port, $path){ final public function __construct($depot, $branch, $port, $path){
$this->p4stream = $stream; $this->p4depot = $depot;
$this->p4branch = $branch;
$this->p4port = $port; $this->p4port = $port;
$this->path = $path; $this->path = $path;
$fs = new Filesystem(); $fs = new Filesystem();
@ -33,7 +36,8 @@ class Perforce {
{ {
if (!isset($this->p4client)){ if (!isset($this->p4client)){
$random_value = mt_rand(1000,9999); $random_value = mt_rand(1000,9999);
$this->p4client = "composer_perforce_" . $random_value . "_".str_replace("/", "_", str_replace("//", "", $this->p4stream)); $clean_stream_name = str_replace("@", "", str_replace("/", "_", str_replace("//", "", $this->p4stream)));
$this->p4client = "composer_perforce_" . $random_value . "_".$clean_stream_name;
} }
return $this->p4client; return $this->p4client;
} }
@ -50,6 +54,7 @@ class Perforce {
{ {
return $this->path; return $this->path;
} }
protected function getPort() protected function getPort()
{ {
return $this->p4port; return $this->p4port;
@ -57,16 +62,80 @@ class Perforce {
protected function getStream() protected function getStream()
{ {
if (!isset($this->p4stream)){
if ($this->isStream()){
$this->p4stream = "//$this->p4depot/$this->p4branch";
} else {
$this->p4stream = "//$this->p4depot";
}
}
return $this->p4stream; return $this->p4stream;
} }
protected function getStreamWithoutLabel()
{
$stream = $this->getStream();
$index = strpos($stream, "@");
if ($index === false){
return $stream;
}
return substr($stream, 0, $index);
}
protected function getP4ClientSpec() protected function getP4ClientSpec()
{ {
$p4clientSpec = $this->path . "/" . $this->getClient() . ".p4.spec"; $p4clientSpec = $this->path . "/" . $this->getClient() . ".p4.spec";
return $p4clientSpec; return $p4clientSpec;
} }
public function syncCodeBase(){ protected function queryP4User(IOInterface $io){
$this->getUser();
if (strlen($this->p4user) <= 0){
$this->p4user = $io->ask("Enter P4 User:");
}
}
protected function queryP4Password(IOInterface $io){
$password = trim(shell_exec('echo $P4PASSWD'));
if (strlen($password) <= 0){
$password = $io->ask("Enter password for Perforce user " . $this->getUser() . ": " );
}
return $password;
}
protected function isStream(){
return (strcmp($this->p4depotType, "stream") === 0);
}
protected function generateP4Command($command, $useClient = true) {
$p4Command = "p4 ";
$p4Command = $p4Command . "-u " . $this->getUser() . " ";
if ($useClient){
$p4Command = $p4Command . "-c " . $this->getClient() . " ";
}
$p4Command = $p4Command . "-p " . $this->getPort() . " ";
$p4Command = $p4Command . $command;
return $p4Command;
}
protected function isLoggedIn(){
$command = $this->generateP4Command("login -s ");
$result = trim(shell_exec($command));
$index = strpos($result, $this->getUser());
if ($index === false){
return false;
}
return true;
}
public function setStream($stream){
$this->p4stream = $stream;
$this->p4depotType = "stream";
}
public function syncCodeBase($label){
$p4CreateClientCommand = $this->generateP4Command( "client -i < " . $this->getP4ClientSpec()); $p4CreateClientCommand = $this->generateP4Command( "client -i < " . $this->getP4ClientSpec());
print ("Perforce: syncCodeBase - client command:$p4CreateClientCommand \n");
$result = shell_exec($p4CreateClientCommand); $result = shell_exec($p4CreateClientCommand);
$prevDir = getcwd(); $prevDir = getcwd();
@ -75,13 +144,19 @@ class Perforce {
$result = shell_exec("pwd"); $result = shell_exec("pwd");
$p4SyncCommand = $this->generateP4Command( "sync -f //".$this->getClient()."/..."); $p4SyncCommand = $this->generateP4Command( "sync -f //".$this->getClient()."/...");
if (isset($label)){
if (strcmp($label, "dev-master") != 0){
$p4SyncCommand = $p4SyncCommand . "@" . $label;
}
}
print ("Perforce: syncCodeBase - sync command:$p4SyncCommand \n");
$result = shell_exec($p4SyncCommand); $result = shell_exec($p4SyncCommand);
chdir($prevDir); chdir($prevDir);
} }
public function writeP4ClientSpec(){ public function writeP4ClientSpec(){
print ("Perforce: writeP4ClientSpec\n");
$spec = fopen($this->getP4ClientSpec(), 'w'); $spec = fopen($this->getP4ClientSpec(), 'w');
try { try {
fwrite($spec, "Client: " . $this->getClient() . "\n\n"); fwrite($spec, "Client: " . $this->getClient() . "\n\n");
@ -94,8 +169,12 @@ class Perforce {
fwrite($spec, "Options: noallwrite noclobber nocompress unlocked modtime rmdir\n\n" ); fwrite($spec, "Options: noallwrite noclobber nocompress unlocked modtime rmdir\n\n" );
fwrite($spec, "SubmitOptions: revertunchanged\n\n" ); fwrite($spec, "SubmitOptions: revertunchanged\n\n" );
fwrite($spec, "LineEnd: local\n\n" ); fwrite($spec, "LineEnd: local\n\n" );
fwrite($spec, "Stream:\n" ); if ($this->isStream()){
fwrite($spec, " " . $this->getStream()."\n" ); fwrite($spec, "Stream:\n" );
fwrite($spec, " " . $this->getStreamWithoutLabel()."\n" );
} else {
fwrite($spec, "View: " . $this->getStream() . "/... //" . $this->getClient() . "/" . str_replace("//", "", $this->getStream()) . "/... \n");
}
} catch(Exception $e){ } catch(Exception $e){
fclose($spec); fclose($spec);
throw $e; throw $e;
@ -105,35 +184,27 @@ class Perforce {
public function getComposerFilePath($identifier) public function getComposerFilePath($identifier)
{ {
$composerFilePath = $this->path . "/composer.json" ; if ($this->isStream()){
print ("\nPerforceUtility - getComposerPath: $composerFilePath\n\n"); $composerFilePath = $this->path . "/composer.json" ;
} else {
$composerFilePath = $this->path . "/" . $this->p4depot . "/composer.json" ;
}
return $composerFilePath; return $composerFilePath;
} }
protected function generateP4Command($command) {
$p4Command = "p4 ";
$p4Command = $p4Command . "-u " . $this->getUser() . " ";
$p4Command = $p4Command . "-c " . $this->getClient() . " ";
$p4Command = $p4Command . "-p " . $this->getPort() . " ";
$p4Command = $p4Command . $command;
return $p4Command;
}
public function p4Login(IOInterface $io){ public function p4Login(IOInterface $io){
$user = $this->getUser(); print ("Perforce: P4Login\n");
$result = trim(shell_exec("p4 login -s")); $this->queryP4User($io);
$index = strpos($result, $user); if (!$this->isLoggedIn()){
if ($index === false){ $password = $this->queryP4Password($io);
$password = trim(shell_exec('echo $P4PASSWD')); $command = "echo $password | " . $this->generateP4Command("login -a ");
if (strlen($password) <= 0){
$password = $io->ask("Enter password for Perforce user " . $this->getUser() . ": " );
}
$command = "echo $password | p4 login -a ";
shell_exec($command); shell_exec($command);
} }
} }
public static function checkServerExists($url) public static function checkServerExists($url)
{ {
print ("Perforce: checkServerExists\n");
$result = shell_exec("p4 -p $url info -s"); $result = shell_exec("p4 -p $url info -s");
$index = strpos($result, "error"); $index = strpos($result, "error");
if ($index === false){ if ($index === false){
@ -144,9 +215,142 @@ class Perforce {
public function getComposerInformation($identifier) public function getComposerInformation($identifier)
{ {
$composerFilePath =$this->getComposerFilePath($identifier); $index = strpos($identifier, "@");
$contents = file_get_contents($composerFilePath); if ($index === false){
$composer_info = json_decode($contents, true); return $this->getComposerInformationFromId($identifier);
return $composer_info; } else {
return $this->getComposerInformationFromTag($identifier, $index);
}
}
public function getComposerInformationFromId($identifier)
{
$composer_json = "$identifier/composer.json";
$command = $this->generateP4Command(" print $composer_json", false);
print ("Perforce: getComposerInformation: command: $command\n\n");
$result = shell_exec($command);
$index = strpos($result, "{");
if ($index === false){
return "";
}
if ($index >=0){
$rawData = substr($result, $index);
$composer_info = json_decode($rawData, true);
print ("ComposerInfo is:".var_export($composer_info, true) . "\n");
return $composer_info;
}
return "";
}
public function getComposerInformationFromTag($identifier, $index)
{
$composer_json = substr($identifier, 0, $index) . "/composer.json" . substr($identifier, $index);
$command = $this->generateP4Command(" files $composer_json", false);
print("\n\nPerforce: getComposerInformationFromTag: $identifier, command:\n $command\n\n");
$result = shell_exec($command);
print("\n\nPerforce: getComposerInformationFromTag: result: \n $result\n\n");
$index2 = strpos($result, "no such file(s).");
if ($index2 === false){
$index3 = strpos($result, "change");
if (!($index3 ===false )){
$phrase = trim(substr($result, $index3));
$fields = explode(" ", $phrase);
$id = $fields[1];
$composer_json = substr($identifier, 0, $index) . "/composer.json@" . $id;
$command = $this->generateP4Command(" print $composer_json", false);
$result = shell_exec($command);
$index = strpos($result, "{");
if ($index === false){
return "";
}
if ($index >=0){
$rawData = substr($result, $index);
$composer_info = json_decode($rawData, true);
print ("ComposerInfo is:".var_export($composer_info, true) . "\n");
return $composer_info;
}
}
}
return "";
}
// public function getComposerInformation($identifier)
// {
// $composerFilePath =$this->getComposerFilePath($identifier);
// $contents = file_get_contents($composerFilePath);
// $composer_info = json_decode($contents, true);
// return $composer_info;
// }
public function getBranches()
{
$branches = array();
if (!$this->isStream()){
$branches[$this->p4branch] = $this->p4stream;
} else {
$command = $this->generateP4Command("streams //$this->p4depot/...");
$result = shell_exec($command);
print ("Perforce: getBranches: result: $result\n");
$resArray = explode("\n", $result);
foreach ($resArray as $line){
$resBits = explode(" ", $line);
if (count($resBits) > 4){
$branch = substr($resBits[4], 1, strlen($resBits[4])-2);
$branches[$branch] = $resBits[1];
}
}
}
$branches['master'] = $branches[$this->p4branch];
return $branches;
}
public function getTags()
{
$command = $this->generateP4Command("changes " . $this->getStream() . "/...");
print("\nPerforce:getTags - command:($command)\n");
$result = shell_exec($command);
$resArray = explode("\n", $result);
$tags = array();
foreach ($resArray as $line){
$index = strpos($line, "Change");
if (!($index===false)){
// $fields = explode(" ", $line);
// $tags["0.0.".$fields[1]] = $this->getStream() . "@" . $fields[1];
}
}
$command = $this->generateP4Command("labels");
print("\nPerforce:getTags - command:($command)\n");
$result = shell_exec($command);
$resArray = explode("\n", $result);
print("\nPerforce:getTags - result:$result\n");
foreach ($resArray as $line){
$index = strpos($line, "Label");
if (!($index===false)){
$fields = explode(" ", $line);
$tags[$fields[1]] = $this->getStream()."@" . $fields[1];
}
}
print ("Perforce:getTags - tags:" . var_export($tags, true)."\n");
return $tags;
}
public function checkStream ()
{
$command = $this->generateP4Command("depots");
$result = shell_exec($command);
$resArray = explode("\n", $result);
foreach ($resArray as $line){
$index = strpos($line, "Depot");
if (!($index===false)){
$fields = explode(" ", $line);
if (strcmp($this->p4depot, $fields[1]) === 0){
$this->p4depotType = $fields[3];
return $this->isStream();
}
}
}
return false;
} }
} }