protected function execute(InputInterface $input, OutputInterface $output)
 {
     set_time_limit(10800);
     // 3 hours is the maximum for this command. Need more? You really screwed something, full suite for all Oblivion vanilla data takes 20 minutes. :)
     try {
         $target = $input->getArgument('target');
         $this->threadsNumber = $input->getArgument('threadsNumber');
         $buildTarget = BuildTargetFactory::get($target);
         if (count(array_slice(scandir($buildTarget->getWorkspacePath()), 2)) > 0 || count(array_slice(scandir($buildTarget->getTranspiledPath()), 2)) > 0 || count(array_slice(scandir($buildTarget->getArtifactsPath()), 2)) > 0) {
             $output->writeln("Target " . $target . " current build dir not clean, archive it manually.");
             return;
         }
         $output->writeln("Starting transpiling reactor using " . $this->threadsNumber . " threads...");
         $reactor = \Amp\reactor();
         $reactor->run(function () use($buildTarget, $output, $reactor) {
             $errorLog = fopen($buildTarget->getErrorLogPath(), "w+");
             $sourceFiles = array_slice(scandir($buildTarget->getSourcePath()), 2);
             $buildPlanBuilder = new TES5BuildPlanBuilder(unserialize(file_get_contents('app/graph')));
             $buildPlan = $buildPlanBuilder->createBuildPlan($sourceFiles, $this->threadsNumber);
             $totalSourceFiles = count($sourceFiles);
             $progressBar = new CliProgressBar($totalSourceFiles);
             $progressBar->display();
             $promises = [];
             foreach ($buildPlan as $threadBuildPlan) {
                 $task = new TranspileChunkJob($buildTarget->getTargetName(), $threadBuildPlan);
                 $deferred = new \Amp\Deferred();
                 \Amp\once(function () use($deferred, $task) {
                     $task->runTask($deferred);
                 }, 0);
                 $promise = $deferred->promise();
                 $promise->when(function (\Exception $e = null, $return = null) use($output, $errorLog) {
                     if ($e) {
                         $output->writeln('Exception ' . get_class($e) . ' occurred in one of the threads while transpiling, progress bar will not be accurate..');
                         fwrite($errorLog, get_class($e) . PHP_EOL . $e->getMessage() . PHP_EOL);
                     }
                 });
                 $promise->watch(function ($data) use($progressBar, $errorLog) {
                     $progressBar->progress(count($data['scripts']));
                     if (isset($data['exception'])) {
                         fwrite($errorLog, implode(', ', $data['scripts']) . PHP_EOL . $data['exception']);
                     }
                 });
                 $promises[] = $promise;
             }
             /**
              * @var Promise $transpilingPromise
              */
             $transpilingPromise = \Amp\any($promises);
             $transpilingPromise->when(function () use($reactor, $progressBar, $errorLog) {
                 $progressBar->end();
                 fclose($errorLog);
                 $reactor->stop();
             });
         });
         $output->writeln("Preparing build workspace...");
         /*
          *
          * @TODO - Create a factory that will provide a PrepareWorkspaceJob based on running system, so we can provide a
          * native implementation for Windows
          */
         $prepareCommand = new PrepareWorkspaceJob($buildTarget->getTargetName());
         $prepareCommand->run();
         $output->writeln("Workspace prepared...");
         $task = new CompileScriptJob($buildTarget->getTargetName());
         $task->run();
         $output->writeln("Build completed, archiving ...");
         /*
          *
          * @TODO - Create a factory that will provide a PrepareWorkspaceJob based on running system, so we can provide a
          * native implementation for Windows
          */
         $prepareCommand = new ArchiveBuildJob($buildTarget->getTargetName());
         $prepareCommand->run();
     } catch (\LogicException $e) {
         $output->writeln("Unknown target " . $target . ", exiting.");
         return;
     } catch (\Exception $e) {
         var_dump($e->getMessage());
         exit;
     }
 }
Example #2
0
<?php

require_once './../vendor/autoload.php';
use Dariuszp\CliProgressBar;
$bar = new CliProgressBar(10, 3);
$bar->displayAlternateProgressBar();
$bar->display();
$bar->end();
 /**
  * @expectedException InvalidArgumentException
  */
 public function testInvalidSetProgressTo()
 {
     $bar = new CliProgressBar();
     $bar->setProgressTo(-10);
 }
Example #4
0
 /**
  * Process all added schemas.
  */
 public function processSchemas()
 {
     echo "" . str_pad("Gathering operations for {$this->database}...", 100, ' ', STR_PAD_RIGHT);
     $sql = implode("\n", $this->schemas);
     list($sql, $drop) = $this->hoist('@^DROP .*?;$@ms', $sql);
     $operations = $drop;
     list($sql, $alter) = $this->hoist('@^ALTER TABLE .*?;$@ms', $sql);
     // Gather all conditionals and optionally wrap them in a "lambda".
     list($sql, $ifs) = $this->hoist('@^IF.*?^END IF;$@ms', $sql);
     foreach ($ifs as &$if) {
         $if = $this->wrapInProcedure($if);
     }
     $operations = array_merge($operations, $ifs);
     list($sql, $tables) = $this->hoist('@^CREATE([A-Z]|\\s)*(TABLE|SEQUENCE) .*?;$@ms', $sql);
     // Hoist all other recreatable objects.
     list($sql, $procedures) = $this->hoist(static::REGEX_PROCEDURES, $sql);
     list($sql, $triggers) = $this->hoist(static::REGEX_TRIGGERS, $sql);
     $hoists = array_merge($procedures, $triggers);
     list($sql, $views) = $this->hoist('@^CREATE VIEW.*?;$@ms', $sql);
     $operations = array_merge($operations, $this->dropRecreatables());
     $tablenames = [];
     foreach ($tables as $table) {
         if (!preg_match('@^CREATE.*?TABLE (\\w+) ?\\(@', $table, $name)) {
             $operations[] = $table;
             continue;
         }
         $name = $name[1];
         $tablenames[] = $name;
         // If the table doesn't exist yet, create it verbatim.
         if (!$this->tableExists($name)) {
             $operations[] = $table;
         } else {
             $existing = $this->getTableDefinition($name);
             $new = $this->parseTableDefinition($table);
             foreach ($existing as $col => $definition) {
                 if (!isset($new[$col])) {
                     $operations[] = sprintf("ALTER TABLE %s DROP COLUMN %s", $name, $col);
                 }
             }
             foreach ($new as $col => $definition) {
                 if (!isset($existing[$col])) {
                     $operations[] = $this->addColumn($name, $definition);
                 } else {
                     $comp = $definition;
                     unset($comp['key']);
                     if ($comp != $existing[$col]) {
                         $operations = array_merge($operations, $this->alterColumn($name, $definition));
                     }
                 }
                 if (isset($definition['key']) && $definition['key'] == 'PRI') {
                     $operations[] = sprintf("ALTER TABLE %s ADD PRIMARY KEY(%s)", $name, $col);
                 }
             }
         }
     }
     foreach ($hoists as $hoist) {
         preg_match('@^CREATE (\\w+) (\\w+)@', $hoist, $data);
         if ($data[1] == 'FUNCTION' && $this instanceof Pgsql) {
             $data[2] .= '()';
         }
         $operations[] = "DROP {$data[1]} IF EXISTS {$data[2]}";
         $operations[] = $hoist;
     }
     if (strlen(trim($sql))) {
         $operations[] = $sql;
     }
     // Recrate views
     $operations = array_merge($operations, $views);
     // Rerun ifs and alters
     $operations = array_merge($operations, $alter, $ifs);
     // Cleanup: remove tables that are not in the schema (any more)
     foreach ($this->getTables('BASE TABLE') as $table) {
         if (!in_array($table, $tablenames) && !$this->shouldIgnore($table)) {
             $operations[] = "DROP TABLE {$table} CASCADE";
         }
     }
     // Perform the actual operations and display progress meter
     echo "Performing operations for {$this->database}...\n";
     echo "";
     $bar = new CliProgressBar(count($operations));
     $bar->display();
     $bar->setColorToRed();
     $fails = [];
     while ($operation = array_shift($operations)) {
         try {
             $this->pdo->exec($operation);
         } catch (PDOException $e) {
             if (preg_match("@(ALTER|CREATE)@", $operation)) {
                 $fails[$operation] = $e->getMessage();
             }
         }
         $bar->progress();
         if ($bar->getCurrentstep() >= $bar->getSteps() / 2) {
             $bar->setColorToYellow();
         }
     }
     $bar->setColorToGreen();
     $bar->display();
     $bar->end();
     echo "";
     if ($fails) {
         echo "The following operations raised an exception:\n";
         echo "(This might not be a problem necessarily):\n";
         foreach ($fails as $command => $reason) {
             echo "{$command}: {$reason}\n";
         }
     }
 }
<?php

require_once './../vendor/autoload.php';
use Dariuszp\CliProgressBar;
$bar = new CliProgressBar(48);
$bar->setBarLength(5);
$bar->display();
$bar->setColorToRed();
while ($bar->getCurrentstep() < $bar->getSteps()) {
    usleep(50000);
    $bar->progress();
    if ($bar->getCurrentstep() >= $bar->getSteps() / 2) {
        $bar->setColorToYellow();
    }
}
$bar->setColorToGreen();
$bar->display();
$bar->end();
Example #6
0
<?php

require_once './../vendor/autoload.php';
use Dariuszp\CliProgressBar;
$bar = new CliProgressBar(10, 3);
print "THIS WILL NOT WORK UNDER WINDOWS (PROBABLY)\n\n";
print "BLACK\n";
$bar->setColorToBlack();
$bar->display();
$bar->end();
print "\nRED\n";
$bar->setColorToRed();
$bar->display();
$bar->end();
print "\nGREEN\n";
$bar->setColorToGreen();
$bar->display();
$bar->end();
print "\nYELLOW\n";
$bar->setColorToYellow();
$bar->display();
$bar->end();
print "\nBLUE\n\n";
$bar->setColorToBlue();
$bar->display();
$bar->end();
print "\nMAGENTA\n\n";
$bar->setColorToMagenta();
$bar->display();
$bar->end();
print "\nCYAN\n\n";
 protected function execute(InputInterface $input, OutputInterface $output)
 {
     set_time_limit(10800);
     $target = 'Standalone';
     $errorLog = fopen("graph_error_log", "w+");
     $log = fopen("graph_debug_log", "w+");
     $buildTarget = BuildTargetFactory::get($target);
     if (count(array_slice(scandir($buildTarget->getWorkspacePath()), 2)) > 0 || count(array_slice(scandir($buildTarget->getTranspiledPath()), 2)) > 0 || count(array_slice(scandir($buildTarget->getArtifactsPath()), 2)) > 0) {
         $output->writeln("Target " . $target . " current build dir not clean, archive it manually.");
         return;
     }
     $sourceFiles = array_slice(scandir($buildTarget->getSourcePath()), 2);
     $inferencer = new TES5TypeInferencer(new ESMAnalyzer(new TypeMapper()), $buildTarget->getSourcePath());
     $dependencyGraph = [];
     $usageGraph = [];
     $progressBar = new CliProgressBar(count($sourceFiles));
     $progressBar->display();
     foreach ($sourceFiles as $sourceFile) {
         try {
             $scriptName = substr($sourceFile, 0, -4);
             $AST = $buildTarget->getAST($buildTarget->getSourceFromPath($scriptName));
             /**
              * @var TES4ObjectProperty[] $propertiesAccesses
              */
             $propertiesAccesses = [];
             $AST->filter(function ($data) use(&$propertiesAccesses) {
                 if ($data instanceof TES4ObjectProperty) {
                     $propertiesAccesses[] = $data;
                 }
             });
             /**
              * @var TES5Property[] $preparedProperties
              */
             $preparedProperties = [];
             /**
              * @var TES5Type[] $preparedPropertiesTypes
              */
             $preparedPropertiesTypes = [];
             foreach ($propertiesAccesses as $property) {
                 preg_match("#([0-9a-zA-Z]+)\\.([0-9a-zA-Z]+)#i", $property->getData(), $matches);
                 $propertyName = $matches[1];
                 $propertyKeyName = strtolower($propertyName);
                 if (!isset($preparedProperties[$propertyKeyName])) {
                     $preparedProperty = new TES5Property($propertyName, TES5BasicType::T_FORM(), $matches[1]);
                     $preparedProperties[$propertyKeyName] = $preparedProperty;
                     $inferencingType = $inferencer->resolveInferenceTypeByReferenceEdid($preparedProperty);
                     $preparedPropertiesTypes[$propertyKeyName] = $inferencingType;
                 } else {
                     $preparedProperty = $preparedProperties[$propertyKeyName];
                     $inferencingType = $inferencer->resolveInferenceTypeByReferenceEdid($preparedProperty);
                     if ($inferencingType != $preparedPropertiesTypes[$propertyKeyName]) {
                         throw new ConversionException("Cannot settle up the properties types - conflict.");
                     }
                 }
             }
             fwrite($log, $scriptName . " - " . count($preparedProperties) . " prepared" . PHP_EOL);
             foreach ($preparedProperties as $preparedPropertyKey => $preparedProperty) {
                 //Only keys are lowercased.
                 $lowerPropertyType = strtolower($preparedPropertiesTypes[$preparedPropertyKey]->value());
                 $lowerScriptType = strtolower($scriptName);
                 if (!isset($dependencyGraph[$lowerPropertyType])) {
                     $dependencyGraph[$lowerPropertyType] = [];
                 }
                 $dependencyGraph[$lowerPropertyType][] = $lowerScriptType;
                 if (!isset($usageGraph[$lowerScriptType])) {
                     $usageGraph[$lowerScriptType] = [];
                 }
                 $usageGraph[$lowerScriptType][] = $lowerPropertyType;
                 fwrite($log, 'Registering a dependency from ' . $scriptName . ' to ' . $preparedPropertiesTypes[$preparedPropertyKey]->value() . PHP_EOL);
             }
             $progressBar->progress();
         } catch (\Exception $e) {
             fwrite($errorLog, $sourceFile . PHP_EOL . $e->getMessage());
             continue;
         }
     }
     $progressBar->end();
     $graph = new TES5ScriptDependencyGraph($dependencyGraph, $usageGraph);
     file_put_contents('app/graph', serialize($graph));
     fclose($errorLog);
     fclose($log);
 }