Commits

Anonymous committed 0273899

* Initial commit of basic working code for the 'cat' command.

More tests need to be run, and unit tests written. Definitely no TDD going on here...

  • Participants
  • Parent commits fbfea5c

Comments (0)

Files changed (4)

Trunk/Tests/Functional/test_Cat.php

+<?php
+
+include_once '../VersionControl/Hg.php';
+
+$hg = new VersionControl_Hg('H:\Development\_Webroot\Trunk\Tests\Fixtures\Test_Repository');
+
+//var_dump($hg->cat('index.php')->run());
+
+
+var_dump($hg->cat('data.xml')->save()->to(realpath('H:\Development\_Webroot\Trunk\Tests\Fixtures'))->run());
+die;
+
+$hg->cat(array('index.php', 'layout.html'))->save()->to(realpath('H:\Development\_Webroot\Trunk\Tests\Fixtures'))->run();
+
+$hg = new VersionControl_Hg('/path/to/repo');
+$hg->cat('/path/to/a/file')->run();
+
+
+//You may also specify multiple files:
+
+$hg = new VersionControl_Hg('/path/to/repo');
+$hg->cat(array('file1', 'file2'))->run();
+
+
+//Additionaly, you may cat the contents of a file at a specific revision:
+
+$hg = new VersionControl_Hg('/path/to/repo');
+$contents = $hg->cat('file2')->revision(6)->run();
+file_put_contents('file2', $content);
+
+//Not specifying a revision causes Mercurial to cat the latest version of the
+//file.
+
+//As a convenience for the latter operation, a programmer may use the save()
+//method:
+
+$hg = new VersionControl_Hg('/path/to/repo');
+$hg->cat('file2')->revision(6)->save('new_file_name')->to('/path')->run();
+
+
+//or, spell out the options in an array:
+
+$hg->cat('file2')->save(array('name' => 'new_file_name', 'to' => '/path'))->run();

Trunk/Tests/Unit/Command/CatTest.php

+<?php
+
+require_once 'H:\Development\_Webroot\Trunk\VersionControl\Hg\Command\Cat.php';
+
+/**
+ * Test class for VersionControl_Hg_Command_Cat.
+ * Generated by PHPUnit on 2011-06-21 at 10:17:44.
+ */
+class VersionControl_Hg_Command_CatTest extends PHPUnit_Framework_TestCase
+{
+    /**
+     * @var VersionControl_Hg_Command_Cat
+     */
+    protected $object;
+
+    /**
+     * Sets up the fixture, for example, opens a network connection.
+     * This method is called before a test is executed.
+     */
+    protected function setUp()
+    {
+        $this->object = new VersionControl_Hg_Command_Cat;
+    }
+
+    /**
+     * Tears down the fixture, for example, closes a network connection.
+     * This method is called after a test is executed.
+     */
+    protected function tearDown()
+    {
+    }
+
+    /**
+     * @todo Implement testExecute().
+     */
+    public function testExecute()
+    {
+        // Remove the following lines when you implement this test.
+        $this->markTestIncomplete(
+          'This test has not been implemented yet.'
+        );
+    }
+
+    /**
+     * @todo Implement testRevision().
+     */
+    public function testRevision()
+    {
+        // Remove the following lines when you implement this test.
+        $this->markTestIncomplete(
+          'This test has not been implemented yet.'
+        );
+    }
+
+    /**
+     * @todo Implement testSave().
+     */
+    public function testSave()
+    {
+        // Remove the following lines when you implement this test.
+        $this->markTestIncomplete(
+          'This test has not been implemented yet.'
+        );
+    }
+
+    /**
+     * @todo Implement testTo().
+     */
+    public function testTo()
+    {
+        // Remove the following lines when you implement this test.
+        $this->markTestIncomplete(
+          'This test has not been implemented yet.'
+        );
+    }
+}
+?>

Trunk/VersionControl/Hg/Command/Cat.php

+<?php
+/**
+ * Contains the definition of the VersionControl_Hg_Repository_Command_Cat
+ * class
+ *
+ * PHP version 5
+ *
+ * @category   VersionControl
+ * @package    Hg
+ * @subpackage Command
+ * @author     Michael Gatto <mgatto@lisantra.com>
+ * @copyright  2011 Lisantra Technologies, LLC
+ * @license    http://www.opensource.org/licenses/mit-license.html  MIT License
+ * @link       http://pear.php.net/package/VersionControl_Hg
+ * @filesource
+ */
+
+/**
+ * Provides the required interface for all commands
+ */
+require_once 'Interface.php';
+
+/**
+ * Provides base functionality common to all commands
+ */
+require_once 'Abstract.php';
+
+/**
+ * Provides Exceptions for commands (VersionControl_Hg_Command_Exception)
+ */
+require_once 'Exception.php';
+
+/**
+ * Print the contents of a file from a specific revision
+ *
+ * Usage:
+ * <code>
+ * $hg = new VersionControl_Hg('/path/to/repo');
+ * $hg->cat('/path/to/a/file')->run();
+ * </code>
+ *
+ * You may also specify multiple files:
+ * <code>
+ * $hg = new VersionControl_Hg('/path/to/repo');
+ * $hg->cat(array('file1', 'file2'))->run();
+ * </code>
+ *
+ * Additionaly, you may cat the contents of a file at a specific revision:
+ * <code>
+ * $hg = new VersionControl_Hg('/path/to/repo');
+ * $contents = $hg->cat('file2')->revision(6)->run();
+ * file_put_contents('file2', $content);
+ * </code>
+ * Not specifying a revision causes Mercurial to cat the latest version of the
+ * file.
+ *
+ * As a convenience for the latter operation, a programmer may use the save()
+ * method:
+ * <code>
+ * $hg = new VersionControl_Hg('/path/to/repo');
+ * $hg->cat('file2')->revision(6)->save('new_file_name')->to('/path')->run();
+ * </code>
+ *
+ * or, spell out the options in an array:
+ * <code>
+ * $hg->cat('file2')->save(array('name' => 'new_file_name', 'to' => '/path'))->run();
+ * </code>
+ *
+ * Note: if you really need multiple files, consider using the Archive command.
+ *
+ * PHP version 5
+ *
+ * @category   VersionControl
+ * @package    Hg
+ * @subpackage Command
+ * @author     Michael Gatto <mgatto@lisantra.com>
+ * @copyright  2011 Lisantra Technologies, LLC
+ * @license    http://www.opensource.org/licenses/mit-license.html  MIT License
+ * @link       http://pear.php.net/package/VersionControl_Hg
+ */
+class VersionControl_Hg_Command_Cat
+    extends VersionControl_Hg_Command_Abstract
+        implements VersionControl_Hg_Command_Interface
+{
+    /**
+     * The name of the mercurial command implemented here
+     *
+     * @var string
+     */
+    protected $command = 'cat';
+
+    /**
+     * Required options for this specific command. These may not be required
+     * by Mercurial itself, but are required for the proper functioning of
+     * this package.
+     *
+     * @var mixed
+     */
+    protected $required_options = array(
+        'noninteractive' => null,
+        'repository' => null,
+        'files' => null,
+    );
+
+    /**
+     * Permissable options.
+     *
+     * The actual option must be the key, while 'null' is a value here to
+     * accommodate the current implementation of setting options.
+     *
+     * @var mixed
+     */
+    protected $allowed_options = array(
+        'save' => null,
+        'to' => null,
+        'revision' => null,
+        'output' => null,
+    );
+
+    /**
+     * Constructor
+     *
+     * @param VersionControl_Hg $hg     The base Hg instance
+     * @param mixed             $params One or more parameters to modify the command
+     *
+     * @return void
+     */
+    public function __construct(VersionControl_Hg $hg, $params = null)
+    {
+        $this->hg = $hg;
+
+        /* should always be called so we have a full array of valid options */
+        $this->setOptions(array()); //$params
+
+        /* We handle the actual param handling here, since we only expect
+         * 1 or more file names. */
+        if ( is_array($params) ) {
+            $this->addOption('files', join(' ', $params));
+        } elseif ( is_scalar($params) ) {
+            $this->addOption('files', $params);
+        } elseif ( is_null($params) ) {
+            //throw an exception
+        }
+    }
+
+    /**
+     * Execute the command and return the results.
+     *
+     * @param mixed $params The options passed to the Log command
+     *
+     * @return string
+     */
+    public function execute(array $params = null)
+    {
+        /* take care of options passed into run() as such:
+         * $hg->cat('/file/')->run('verbose'));
+         * Although, 'verbose|quiet' probably have no effect...?
+         */
+        if ( ! empty($params) ) {
+            $this->setOptions($params);
+        }
+
+        /* --noninteractive is required since issuing the command is
+         * unattended by nature of using this package.
+         *
+         * --repository PATH is required since the PWD on which hg is invoked
+         * will not be within the working copy of the repo. */
+        $this->addOptions(
+            array(
+                'noninteractive' => null,
+                'repository' => $this->hg->getRepository()->getPath(),
+                'cwd' => $this->hg->getRepository()->getPath(),
+            )
+        );
+
+        /* Despite its being so not variable, we need to set the command string
+         * only after manually setting options and other command-specific data */
+        $this->setCommandString();
+
+        //var_dump($this->command_string);
+
+        /* no var assignment, since 2nd param holds output */
+        exec($this->command_string, $this->output, $this->status);
+
+        if ( $this->status !== 0 ) {
+            throw new VersionControl_Hg_Command_Exception(
+                VersionControl_Hg_Command_Exception::COMMANDLINE_ERROR
+            );
+        }
+
+        /*return $this->parseOutput(
+            $this->output,
+            array('rev', 'branch', 'files', 'datetime', 'author', 'description'),
+            '##'
+        );*/
+
+        return $this->output;
+    }
+
+    /**
+     * Specified the revision to restrict the cat operation to
+     *
+     * Usage:
+     * <code>$hg->cat('file_name')->revision(7)->run();</code>
+     * or
+     * <code>$hg->cat(array('revision' => 7 ))->run();</code>
+     *
+     * @param string $revision is the optional revision to cat
+     *
+     * @return void
+     */
+    public function revision($revision = 'tip')
+    {
+        $this->addOption('rev', $revision);
+
+        /* for the fluent API */
+        return $this;
+    }
+
+    /**
+     * set the --output options to designate a file name and directory to
+     * where the catted file will be saved
+     *
+     * @param string $name The name of the file name
+     *
+     * @return VersionControl_Hg_Command_Abstract
+     */
+    public function save($name = '%s')
+    {
+        //@TODO allow array of new filenames to match multiple files
+        // provided to cat()
+
+        //We allow this syntax, too: save(array('name' => '', 'to' => ''))
+        if ( is_array($name) ) {
+            //check that both 'name' and 'to' keys are set
+            if ( count(array_keys($name, array('to', 'name'))) != 2 ) {
+                //throw an exception, BUT, what if we allow programmer to pass
+                // save(array('name' => 'file'))->to('/path/')? should we just
+                // disallow that?
+            }
+
+            $this->addOptions($params);
+        } elseif ( is_scalar($name) ) {
+            $this->addOption('output', $name);
+        }
+
+        /* for fluent api */
+        return $this;
+    }
+
+     /**
+     * Modifies the --output option to set the directory path to which the
+     * catted file will be saved
+     *
+     * Defaults to the current directory, specified by --cwd and usually is
+     * the same as the repository path.
+     *
+     * @param string $directory is directory to which archives are saved
+     *
+     * @return VersionControl_Hg_Command_Abstract
+     * @throws VersionControl_Hg_Repository_Command_Exception
+     */
+    public function to($directory = '.')
+    {
+        /* test path's validity */
+        if ( $directory != realpath($directory) ) {
+            throw new VersionControl_Hg_Repository_Command_Exception(
+                VersionControl_Hg_Command_Exception::BAD_ARGUMENT,
+                "The path '{$directory}' does not seem to exist on
+                this server. "
+            );
+        }
+
+        $output_template = $this->getOption('output');
+
+        /* append the directory to --output */
+        $output_template = $directory . DIRECTORY_SEPARATOR . $output_template;
+
+        /* now, add it back to the stack of options... */
+        $this->options['output'] = $output_template;
+
+        /* for the fluent api */
+        return $this;
+    }
+
+}

Trunk/VersionControl/Hg/CommandProxy.php

      * @var array
      */
     protected $allowed_commands = array(
-        'version', 'archive', 'status', 'log', 'init', 'clone', 'pull',
+        'version', 'archive', 'status', 'log', 'init', 'clone', 'pull', 'cat'
     );
 
     /**