فهرست منبع

Added Perforce to Composer

matt-whittom 12 سال پیش
والد
کامیت
0d061f2530

+ 109 - 0
src/Composer/Downloader/PerforceDownloader.php

@@ -0,0 +1,109 @@
+<?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\Downloader;
+
+use Composer\Package\PackageInterface;
+use Composer\Util\Perforce;
+#use Composer\Util\GitHub;
+#use Composer\Util\Git as GitUtil;
+
+/**
+ * @author Jordi Boggiano <j.boggiano@seld.be>
+ */
+class PerforceDownloader extends VcsDownloader
+{
+    private $hasStashedChanges = false;
+
+    /**
+     * {@inheritDoc}
+     */
+    public function doDownload(PackageInterface $package, $path)
+    {
+        print ("Perforce Downloader:doDownload - path:" . var_export($path, true) . "\n");
+
+        $ref = $package->getSourceReference();
+        $p4client = "composer_perforce_dl_" . str_replace("/", "_", str_replace("//", "", $ref));
+
+        $clientSpec = "$path/$p4client.p4.spec";
+        print ("PerforceDownloader:doDownload - clientSpec: $clientSpec, targetDir: $path, p4Client: $p4client\n\n");
+        $perforce = new Perforce();
+        $perforce->writeP4ClientSpec($clientSpec, $path, $p4client, $ref);
+        $perforce->syncCodeBase($clientSpec, $path, $p4client);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function doUpdate(PackageInterface $initial, PackageInterface $target, $path)
+    {
+        print("PerforceDownloader:doUpdate\n");
+
+//        $this->cleanEnv();
+//        $path = $this->normalizePath($path);
+//
+//        $ref = $target->getSourceReference();
+//        $this->io->write("    Checking out ".$ref);
+//        $command = 'git remote set-url composer %s && git fetch composer && git fetch --tags composer';
+//
+//        // capture username/password from URL if there is one
+//        $this->process->execute('git remote -v', $output, $path);
+//        if (preg_match('{^(?:composer|origin)\s+https?://(.+):(.+)@([^/]+)}im', $output, $match)) {
+//            $this->io->setAuthentication($match[3], urldecode($match[1]), urldecode($match[2]));
+//        }
+//
+//        $commandCallable = function($url) use ($command) {
+//            return sprintf($command, escapeshellarg($url));
+//        };
+//
+//        $this->runCommand($commandCallable, $target->getSourceUrl(), $path);
+//        $this->updateToCommit($path, $ref, $target->getPrettyVersion(), $target->getReleaseDate());
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getLocalChanges($path)
+    {
+        print("PerforceDownloader:getLocalChanges\n");
+//        $this->cleanEnv();
+//        $path = $this->normalizePath($path);
+//        if (!is_dir($path.'/.git')) {
+//            return;
+//        }
+//
+//        $command = 'git status --porcelain --untracked-files=no';
+//        if (0 !== $this->process->execute($command, $output, $path)) {
+//            throw new \RuntimeException('Failed to execute ' . $command . "\n\n" . $this->process->getErrorOutput());
+//        }
+//
+//        return trim($output) ?: null;
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    protected function getCommitLogs($fromReference, $toReference, $path)
+    {
+        print("PerforceDownloader:getCommitLogs\n");
+//        $path = $this->normalizePath($path);
+//        $command = sprintf('git log %s..%s --pretty=format:"%%h - %%an: %%s"', $fromReference, $toReference);
+//
+//        if (0 !== $this->process->execute($command, $output, $path)) {
+//            throw new \RuntimeException('Failed to execute ' . $command . "\n\n" . $this->process->getErrorOutput());
+//        }
+//
+//        return $output;
+    }
+
+}

+ 218 - 0
src/Composer/Repository/Vcs/PerforceDriver.php

@@ -0,0 +1,218 @@
+<?php
+
+/*
+ * This file is part of Composer.
+ *
+ * (c) Nils Adermann <naderman@naderman.de>
+ *     Jordi Boggiano <j.boggiano@seld.be>
+ *
+ *  Contributor: matt-whittom
+ *  Date: 7/17/13
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Composer\Repository\Vcs;
+
+#use Composer\Downloader\TransportException;
+#use Composer\Json\JsonFile;
+#use Composer\Cache;
+use Composer\IO\IOInterface;
+use Composer\Util\Filesystem;
+use Composer\Util\Perforce;
+#use Composer\Util\RemoteFilesystem;
+#use Composer\Util\GitHub;
+
+/**
+ * @author matt-whittom <>
+ */
+class PerforceDriver extends VcsDriver
+{
+//    protected $cache;
+//    protected $owner;
+//    protected $repository;
+//    protected $tags;
+//    protected $branches;
+    protected $rootIdentifier = 'mainline';
+    protected $repoDir;
+//    protected $hasIssues;
+//    protected $infoCache = array();
+//    protected $isPrivate = false;
+    protected $depot;
+    protected $p4client;
+
+    /**
+     * {@inheritDoc}
+     */
+    public function initialize()
+    {
+        print ("PerforceDriver:initialize\n");
+        $this->depot = $this->repoConfig['depot'];
+        $this->p4client = "composer_perforce_$this->depot";
+        $this->repoDir = $this->config->get('cache-vcs-dir') . "/$this->depot";
+        $clientSpec = $this->config->get('cache-dir') . "/perforce/$this->p4client.p4.spec";
+
+        $this->p4Login();
+
+        $fs = new Filesystem();
+        $fs->ensureDirectoryExists($this->repoDir);
+
+        $stream = "//$this->depot/$this->rootIdentifier";
+        $perforce = new Perforce();
+        $perforce->writeP4ClientSpec($clientSpec, $this->repoDir, $this->p4client, $stream);
+        $perforce->syncCodeBase($clientSpec, $this->repoDir, $this->p4client);
+
+        return true;
+    }
+
+    protected function p4Login(){
+        $password = trim(shell_exec('echo $P4PASSWD'));
+        $command = "echo $password | p4 login -a ";
+        shell_exec($command);
+    }
+
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getComposerInformation($identifier)
+    {
+        print ("PerforceDriver:getComposerInformation: $identifier\n");
+        $command = "p4 print $identifier/composer.json";
+        $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;
+        }
+
+
+//   Basically, read the composer.json file from the project.
+//
+//        Git stuff:
+//        ..getComposerInfo is: array (
+//        'support' =>
+//        array (
+//            'source' => 'http://github.com/composer/packagist',
+//        ),
+//        'time' => '2012-09-10',
+//    )
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getRootIdentifier()
+    {
+        print ("PerforceDriver:getRootIdentifier\n");
+        return $this->rootIdentifier;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getBranches()
+    {
+        //return $branch->$identifier
+        //getComposer($identifier)
+        //validate($branch)
+        print ("PerforceDriver:getBranches\n");
+        $command = "p4 streams //$this->depot/...";
+        $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'];
+        print ("PerforceDriver:getBranches - returning branches:".var_export($branches, true)."\n");
+        return $branches;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getTags()
+    {
+        print ("PerforceDriver:getTags\n");
+        return array();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getDist($identifier)
+    {
+        print ("PerforceDriver:getDist: $identifier\n");
+        return null;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getSource($identifier)
+    {
+        print ("PerforceDriver:getSource: $identifier\n");
+
+        $source = array (
+            'type' => 'perforce',
+            'url' => $this->repoConfig['url'],
+            'reference' => $identifier
+        );
+        return $source;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getUrl()
+    {
+        print ("PerforceDriver:getUrl\n");
+
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function hasComposerFile($identifier)
+    {
+        print ("PerforceDriver:hasComposerFile: $identifier\n");
+
+        //Does the project have a composer file?
+        return true;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getContents($url)
+    {
+        print("PerforceDriver:getContents - url: $url");
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public static function supports(IOInterface $io, $url, $deep = false)
+    {
+        print ("PerforceDriver:supports\n");
+
+        print ("\nChecking url for support: $url\n\n");
+        if (preg_match('#(^perforce)#', $url)) {
+            return true;
+        }
+        return false;
+    }
+}

+ 70 - 0
src/Composer/Util/Perforce.php

@@ -0,0 +1,70 @@
+<?php
+/**
+ * Created by JetBrains PhpStorm.
+ * User: matt.whittom
+ * Date: 7/23/13
+ * Time: 3:22 PM
+ * To change this template use File | Settings | File Templates.
+ */
+
+namespace Composer\Util;
+
+
+class Perforce {
+    public function syncCodeBase($clientSpec, $targetDir, $p4client){
+        $p4CreateClientCommand = "p4 client -i < $clientSpec";
+        print ("\nPerforceDriver create client: $p4CreateClientCommand\n");
+        $result = shell_exec($p4CreateClientCommand);
+        print ("result: $result\n\n");
+
+        $prevDir = getcwd();
+        chdir($targetDir);
+
+        //write p4 config file
+        $p4ConfigFileSpec = "$targetDir/p4config.config";
+        $p4ConfigFile = fopen($p4ConfigFileSpec, 'w');
+        fwrite($p4ConfigFile, "P4CLIENT=$p4client");
+        fclose($p4ConfigFile);
+
+        $testCommand = "pwd";
+        print ("PerforceDriver test dir command: $testCommand\n");
+        $result = shell_exec($testCommand);
+        print ("result: $result\n\n");
+
+        $p4SyncCommand = "p4 sync -f //$p4client/...";
+        print ("PerforceDriver sync client: $p4SyncCommand\n");
+        $result = shell_exec($p4SyncCommand);
+        print ("result: $result\n\n");
+
+        chdir($prevDir);
+    }
+
+    public function writeP4ClientSpec($clientSpec, $targetDir, $p4client, $stream){
+        $fs = new Filesystem();
+        $fs->ensureDirectoryExists(dirname($clientSpec));
+
+        $p4user = trim(shell_exec('echo $P4USER'));
+        print ("PerforceDriver: writing to client spec: $clientSpec\n\n");
+        $spec = fopen($clientSpec, 'w');
+        try {
+            fwrite($spec, "Client: $p4client\n\n");
+            fwrite($spec, "Update: " . date("Y/m/d H:i:s") . "\n\n");
+            fwrite($spec, "Access: " . date("Y/m/d H:i:s") . "\n" );
+            fwrite($spec, "Owner:  $p4user\n\n" );
+            fwrite($spec, "Description:\n" );
+            fwrite($spec, "  Created by $p4user from composer.\n\n" );
+            fwrite($spec, "Root: $targetDir\n\n" );
+            fwrite($spec, "Options:  noallwrite noclobber nocompress unlocked modtime rmdir\n\n" );
+            fwrite($spec, "SubmitOptions:  revertunchanged\n\n" );
+            fwrite($spec, "LineEnd:  local\n\n" );
+            fwrite($spec, "Stream:\n" );
+            fwrite($spec, "  $stream\n" );
+        }  catch(Exception $e){
+            fclose($spec);
+            throw $e;
+        }
+        fclose($spec);
+    }
+
+
+}

+ 152 - 0
tests/Composer/Test/Repository/Vcs/PerforceDriverTest.php

@@ -0,0 +1,152 @@
+<?php
+/*
+ * This file is part of Composer.
+ *
+ * (c) Nils Adermann <naderman@naderman.de>
+ *     Jordi Boggiano <j.boggiano@seld.be>
+ *
+ *  Contributor: matt-whittom
+ *  Date: 7/17/13
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Composer\Test\Repository\Vcs;
+
+#use Composer\Downloader\TransportException;
+use Composer\Repository\Vcs\PerforceDriver;
+use Composer\Util\Filesystem;
+use Composer\Config;
+use Composer\IO\ConsoleIO;
+use Symfony\Component\Console\Input\ArrayInput;
+use Symfony\Component\Console\Output\ConsoleOutput;
+use Symfony\Component\Console\Helper\HelperSet;
+
+
+class PerforceDriverTest extends \PHPUnit_Framework_TestCase
+{
+    private $config;
+    private $io;
+
+    public function setUp()
+    {
+        $this->config = new Config();
+        $this->config->merge(array(
+            'config' => array(
+                'home' => sys_get_temp_dir() . '/composer-test',
+            ),
+        ));
+        $inputParameters = array();
+        $input = new ArrayInput($inputParameters);
+        $output = new ConsoleOutput();
+        $helperSet = new HelperSet();
+        $this->io = new ConsoleIO($input, $output, $helperSet);
+    }
+
+    public function tearDown()
+    {
+        $fs = new Filesystem;
+        $fs->removeDirectory(sys_get_temp_dir() . '/composer-test');
+    }
+
+    public function testPrivateRepository()
+    {
+        $repo_config = array(
+            'url' => "perforce.vuhl.root.mrc.local:3710",
+            'depot' => "lighthouse"
+        );
+
+        $vcs = new PerforceDriver($repo_config, $this->io, $this->config);
+        $result = $vcs->initialize();
+        $this->assertTrue($result);
+    }
+
+    public function testGetBranches()
+    {
+        $repo_config = array(
+            'url' => "perforce.vuhl.root.mrc.local:3710",
+            'depot' => "lighthouse"
+        );
+
+        $vcs = new PerforceDriver($repo_config, $this->io, $this->config);
+        $result = $vcs->initialize();
+        $this->assertTrue($result);
+        $branches = $vcs->getBranches();
+        //print ("\nBranches are: " . var_export($branches, true));
+        $this->assertTrue(strcmp($branches['mainline'], "//lighthouse/mainline") == 0);
+    }
+
+    public function testGetTags()
+    {
+        $repo_config = array(
+            'url' => "perforce.vuhl.root.mrc.local:3710",
+            'depot' => "lighthouse"
+        );
+
+        $vcs = new PerforceDriver($repo_config, $this->io, $this->config);
+        $result = $vcs->initialize();
+        $this->assertTrue($result);
+        $tags = $vcs->getTags();
+        $this->assertTrue(empty($tags));
+    }
+
+    public function testGetSource()
+    {
+        $repo_config = array(
+            'url' => "perforce.vuhl.root.mrc.local:3710",
+            'depot' => "lighthouse"
+        );
+
+        $vcs = new PerforceDriver($repo_config, $this->io, $this->config);
+        $result = $vcs->initialize();
+        $this->assertTrue($result);
+        $identifier = $vcs->getRootIdentifier();
+        $source = $vcs->getSource($identifier);
+        $this->assertEquals($source['type'], "perforce");
+        $this->assertEquals($source['reference'], $identifier);
+    }
+
+    public function testGetDist()
+    {
+        $repo_config = array(
+            'url' => "perforce.vuhl.root.mrc.local:3710",
+            'depot' => "lighthouse"
+        );
+
+        $vcs = new PerforceDriver($repo_config, $this->io, $this->config);
+        $result = $vcs->initialize();
+        $this->assertTrue($result);
+        $identifier = $vcs->getRootIdentifier();
+        $dist = $vcs->getDist($identifier);
+        $this->assertNull($dist);
+    }
+
+    public function testGetRootIdentifier(){
+        $repo_config = array(
+            'url' => "perforce.vuhl.root.mrc.local:3710",
+            'depot' => "lighthouse"
+        );
+
+        $vcs = new PerforceDriver($repo_config, $this->io, $this->config);
+        $result = $vcs->initialize();
+        $this->assertTrue($result);
+        $rootId = $vcs->getRootIdentifier();
+        $this->assertEquals("mainline", $rootId);
+    }
+
+    public function testHasComposerFile(){
+        $repo_config = array(
+            'url' => "perforce.vuhl.root.mrc.local:3710",
+            'depot' => "lighthouse"
+        );
+
+        $vcs = new PerforceDriver($repo_config, $this->io, $this->config);
+        $result = $vcs->initialize();
+        $this->assertTrue($result);
+        $identifier = $vcs->getRootIdentifier();
+        $value = $vcs->hasComposerFile($identifier);
+        $this->assertTrue($value);
+    }
+}
+