Add initial command skeleton

* Update dependencies
* Add twig formatters
* Update version command and add version to the package.json
* Update package.json with other project details
This commit is contained in:
Craig Davis
2014-01-12 08:05:09 -07:00
parent 7b909c6cf1
commit b403d712a1
12 changed files with 383 additions and 164 deletions

View File

@@ -1,5 +1,5 @@
<?php
namespace FogBugz\Cli;
namespace Resume\Cli;
use Symfony\Component\Console\Application;
use Symfony\Component\Console\Formatter\OutputFormatterStyle;
@@ -8,70 +8,32 @@ use Symfony\Component\Console\Input\ArgvInput;
use Symfony\Component\Console\Input\ArrayInput;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Output\ConsoleOutput;
use Symfony\Component\Yaml\Yaml;
use There4\FogBugz;
use FogBugz\Cli;
use FogBugz\Command;
use Resume\Cli;
use Resume\Command;
class Working extends Application
class Resume extends Application
{
public $recentCaseLimit = 10;
public $configFile;
public function initialize($configFile, $templatePath, $project)
public function initialize($templatePath, $project)
{
$runSetup = false;
$this->configFile = $configFile;
// Add the composer information for use in version info and such.
$this->project = $project;
// Load our application config information
if (file_exists($configFile)) {
$this->config = Yaml::parse($configFile);
} else {
$runSetup = true;
$this->config = $this->getDefaultConfig();
}
// https://github.com/symfony/Console/blob/master/Output/Output.php
$this->outputFormat
= $this->config['UseColor']
? OutputInterface::OUTPUT_NORMAL
: OutputInterface::OUTPUT_PLAIN;
// the alternative is OutputInterface::OUTPUT_PLAIN;
$this->outputFormat = OutputInterface::OUTPUT_NORMAL;
// We do this now because we've loaded the project info from the composer file
$this->setName($this->project->description);
$this->setVersion($this->project->version);
// Load our commands into the application
$this->add(new Command\AssignCommand());
$this->add(new Command\CasesCommand());
$this->add(new Command\CloseCommand());
$this->add(new Command\CurrentCommand());
$this->add(new Command\EstimateCommand());
$this->add(new Command\FiltersCommand());
$this->add(new Command\LoginCommand());
$this->add(new Command\LogoutCommand());
$this->add(new Command\NoteCommand());
$this->add(new Command\OpenCommand());
$this->add(new Command\ParentCommand());
$this->add(new Command\ReactivateCommand());
$this->add(new Command\RecentCommand());
$this->add(new Command\ReopenCommand());
$this->add(new Command\ResolveCommand());
$this->add(new Command\SearchCommand());
$this->add(new Command\SelfUpdateCommand());
$this->add(new Command\SetFilterCommand());
$this->add(new Command\SetupCommand());
$this->add(new Command\StartCommand());
$this->add(new Command\StarCommand());
$this->add(new Command\StopCommand());
$this->add(new Command\UnstarCommand());
$this->add(new Command\VersionCommand());
$this->add(new Command\ViewCommand());
// We'll use [Twig](http://twig.sensiolabs.org/) for template output
$loader = new \Twig_Loader_Filesystem($templatePath);
@@ -89,26 +51,6 @@ class Working extends Application
$this->twig->addFilter('style', new \Twig_Filter_Function("FogBugz\Cli\TwigFormatters::style"));
$this->twig->addFilter('repeat', new \Twig_Filter_Function("str_repeat"));
$this->twig->addFilter('wrap', new \Twig_Filter_Function("wordwrap"));
// If the config file is empty, run the setup script here
// If the config file version is a different major number, run the setup script here
$currentVersion = explode('.', $this->project->version);
$configVersion = explode('.', $this->config['ConfigVersion']);
$majorVersionChange = $currentVersion[0] != $configVersion[0];
// We need to be able to skip setup for the list and help
$helpRequested = (
empty($_SERVER['argv'][1]) ||
($_SERVER['argv'][1] == 'list') ||
($_SERVER['argv'][1] == 'help')
);
if (($runSetup || $majorVersionChange) && !$helpRequested) {
$command = $this->find('setup');
$arguments = array(
'command' => 'setup'
);
$input = new ArrayInput($arguments);
$command->run($input, new ConsoleOutput());
}
}
public function getLongVersion()
@@ -116,61 +58,6 @@ class Working extends Application
return parent::getLongVersion().' by <comment>Craig Davis</comment>';
}
public function getDefaultConfig()
{
return array(
'ConfigVersion' => '0.0.1',
'UseColor' => true,
'Host' => '',
'User' => '',
'AuthToken' => '',
'RecentCases' => array()
);
}
public function getCurrent($user = '')
{
if ($user === '') {
$user = $this->fogbugz->user;
}
$xml = $this->fogbugz->viewPerson(array('sEmail' => $user));
return (int) $xml->people->person->ixBugWorkingOn;
}
public function getRecent()
{
return
is_array($this->config['RecentCases'])
? $this->config['RecentCases']
: array();
}
public function pushRecent($case, $title)
{
$recentCases = $this->getRecent();
array_push(
$recentCases,
array(
"id" => $case,
"title" => $title
)
);
// Only keep the last x number of cases in the list
$this->config['RecentCases'] = array_slice($recentCases, -1 * $this->recentCaseLimit);
$this->saveConfig();
return true;
}
public function saveConfig()
{
// the second param is the depth for starting yaml inline formatting
$yaml = Yaml::dump($this->config, 2);
return file_put_contents($this->configFile, $yaml);
}
public function registerStyles(&$output)
{
// https://github.com/symfony/Console/blob/master/Formatter/OutputFormatterStyle.php
@@ -241,23 +128,10 @@ class Working extends Application
} catch (\Exception $e) {
exit($e->getMessage() . "\n");
}
// Does the command require authentication?
if (property_exists($command, "requireAuth") && $command->requireAuth) {
$simple_input = new ArgvInput(
array(
$_SERVER['argv'][0],
$_SERVER['argv'][1],
"--quiet"
)
);
$login = $this->find('login');
$returnCode = $login->run($simple_input, $output);
}
}
return parent::run($input, $output);
}
}
/* End of file Working.php */
/* End of file Resume.php */

View File

@@ -0,0 +1,37 @@
<?php
namespace FogBugz\Cli;
class TwigFormatters
{
public static function strpad($string, $length, $position = "center")
{
switch ($position) {
case "left":
$padding = STR_PAD_RIGHT;
break;
case "right":
$padding = STR_PAD_LEFT;
break;
case "center":
default:
$padding = STR_PAD_BOTH;
}
// This must handle tagged strings for our Console formatting
// <info>this is a long title</info>
$total_length = strlen($string);
$stripped_length = strlen(strip_tags($string));
$length = $length + $total_length - $stripped_length;
return str_pad(substr($string, 0, $length), $length, " ", $padding);
}
public static function style($string, $format)
{
return sprintf('<%2$s>%1$s</%2$s>', $string, $format);
}
}
/* End of file TwigFormatters */

View File

@@ -0,0 +1,22 @@
<?php
namespace Resume\Command;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
class HtmlCommand extends Command
{
protected function configure()
{
$this
->setName('html')
->setDescription('Generate an HTML resume from a markdown file');
}
protected function execute(InputInterface $input, OutputInterface $output)
{
}
}
/* End of file HtmlCommand.php */

View File

@@ -0,0 +1,22 @@
<?php
namespace Resume\Command;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
class PdfCommand extends Command
{
protected function configure()
{
$this
->setName('pdf')
->setDescription('Generate a PDF from a markdown file');
}
protected function execute(InputInterface $input, OutputInterface $output)
{
}
}
/* End of file PdfCommand.php */

View File

@@ -0,0 +1,87 @@
<?php
namespace Resume\Command;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
class SelfUpdateCommand extends Command
{
protected function configure()
{
$this
->setName('selfupdate')
->setDescription('Updates fb.phar to the latest version.')
->setHelp(
<<<EOT
The <info>self-update</info> command checks github for newer
versions of the command line client and if found, installs the latest.
EOT
);
}
protected function execute(InputInterface $input, OutputInterface $output)
{
$this->app = $this->getApplication();
$localFilename = realpath($_SERVER['argv'][0]) ?: $_SERVER['argv'][0];
$tempFilename = dirname($localFilename) . '/' . basename($localFilename, '.phar').'-temp.phar';
if (substr($localFilename, -4) === '.php') {
throw new \Exception('You must run this from the compiled phar file.');
}
// check for permissions in local filesystem before start connection process
if (!is_writable($tempDirectory = dirname($tempFilename))) {
throw new \Exception(
'Self update failed: the "' . $tempDirectory
. '" directory used to download the temp file could not be written'
);
}
if (!is_writable($localFilename)) {
throw new \Exception(
'Self update failed: the "' . $localFilename . '" file could not be written'
);
}
$protocol = extension_loaded('openssl') ? 'https' : 'http';
$latest = trim(file_get_contents($protocol . $this->app->project->selfupdateversion, false));
if ($this->app->project->version !== $latest) {
$output->writeln(sprintf("Updating to version <info>%s</info>.", $latest));
$remoteFilename = $protocol . $this->app->project->selfupdatepath;
$phar = file_get_contents($remoteFilename);
file_put_contents($tempFilename, $phar);
if (!file_exists($tempFilename)) {
$output->writeln('<error>The download of the new version failed for an unexpected reason</error>');
return 1;
}
try {
@chmod($tempFilename, 0777 & ~umask());
// test the phar validity
$phar = new \Phar($tempFilename);
// free the variable to unlock the file
unset($phar);
rename($tempFilename, $localFilename);
} catch (\Exception $e) {
@unlink($tempFilename);
if (!$e instanceof \UnexpectedValueException && !$e instanceof \PharException) {
throw $e;
}
$output->writeln('<error>The download is corrupted ('.$e->getMessage().').</error>');
$output->writeln('<error>Please re-run the self-update command to try again.</error>');
}
} else {
$output->writeln("<info>You are using the latest version.</info>");
}
}
}
/* End of file SelfUpdateCommand.php */

View File

@@ -1,24 +1,17 @@
<?php
namespace FogBugz\Command;
namespace Resume\Command;
use FogBugz\Cli\AuthCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
class VersionCommand extends AuthCommand
class VersionCommand extends Command
{
public function __construct()
{
parent::__construct();
}
protected function configure()
{
$this
->setName('version')
->setDescription('Show version information')
->requireAuth(false);
->setDescription('Show current version information');
}
protected function execute(InputInterface $input, OutputInterface $output)