public function lintPath($path)
 {
     $bin = $this->getLintPath();
     $options = $this->getLintOptions();
     $f = new ExecFuture("%C %C -", $bin, $options);
     $f->write($this->getData($path));
     list($err, $stdout, $stderr) = $f->resolve();
     if ($err === 2) {
         throw new Exception("cpplint failed to run correctly:\n" . $stderr);
     }
     $lines = explode("\n", $stderr);
     $messages = array();
     foreach ($lines as $line) {
         $line = trim($line);
         $matches = null;
         $regex = '/^-:(\\d+):\\s*(.*)\\s*\\[(.*)\\] \\[(\\d+)\\]$/';
         if (!preg_match($regex, $line, $matches)) {
             continue;
         }
         foreach ($matches as $key => $match) {
             $matches[$key] = trim($match);
         }
         $message = new ArcanistLintMessage();
         $message->setPath($path);
         $message->setLine($matches[1]);
         $message->setCode($matches[3]);
         $message->setName($matches[3]);
         $message->setDescription($matches[2]);
         $message->setSeverity(ArcanistLintSeverity::SEVERITY_WARNING);
         $this->addLintMessage($message);
     }
 }
Exemplo n.º 2
0
 public function lintPath($path)
 {
     $working_copy = $this->getEngine()->getWorkingCopy();
     $pyflakes_path = $working_copy->getConfig('lint.pyflakes.path');
     $pyflakes_prefix = $working_copy->getConfig('lint.pyflakes.prefix');
     // Default to just finding pyflakes in the users path
     $pyflakes_bin = 'pyflakes';
     $python_path = '';
     // If a pyflakes path was specified, then just use that as the
     // pyflakes binary and assume that the libraries will be imported
     // correctly.
     //
     // If no pyflakes path was specified and a pyflakes prefix was
     // specified, then use the binary from this prefix and add it to
     // the PYTHONPATH environment variable so that the libs are imported
     // correctly.  This is useful when pyflakes is installed into a
     // non-default location.
     if ($pyflakes_path !== null) {
         $pyflakes_bin = $pyflakes_path;
     } else {
         if ($pyflakes_prefix !== null) {
             $pyflakes_bin = $pyflakes_prefix . '/bin/pyflakes';
             $python_path = $pyflakes_prefix . '/lib/python2.6/site-packages:';
         }
     }
     $options = $this->getPyFlakesOptions();
     $f = new ExecFuture("/usr/bin/env PYTHONPATH=%s\$PYTHONPATH " . "{$pyflakes_bin} {$options}", $python_path);
     $f->write($this->getData($path));
     try {
         list($stdout, $_) = $f->resolvex();
     } catch (CommandException $e) {
         // PyFlakes will return an exit code of 1 if warnings/errors
         // are found but print nothing to stderr in this case.  Therefore,
         // if we see any output on stderr or a return code other than 1 or 0,
         // pyflakes failed.
         if ($e->getError() !== 1 || $e->getStderr() !== '') {
             throw $e;
         } else {
             $stdout = $e->getStdout();
         }
     }
     $lines = explode("\n", $stdout);
     $messages = array();
     foreach ($lines as $line) {
         $matches = null;
         if (!preg_match('/^(.*?):(\\d+): (.*)$/', $line, $matches)) {
             continue;
         }
         foreach ($matches as $key => $match) {
             $matches[$key] = trim($match);
         }
         $message = new ArcanistLintMessage();
         $message->setPath($path);
         $message->setLine($matches[2]);
         $message->setCode($this->getLinterName());
         $message->setDescription($matches[3]);
         $message->setSeverity(ArcanistLintSeverity::SEVERITY_WARNING);
         $this->addLintMessage($message);
     }
 }
 public function lintPath($path)
 {
     $rubyp = $this->getRubyPath();
     $f = new ExecFuture("%s -wc", $rubyp);
     $f->write($this->getData($path));
     list($err, $stdout, $stderr) = $f->resolve();
     if ($err === 0) {
         return;
     }
     $lines = explode("\n", $stderr);
     $messages = array();
     foreach ($lines as $line) {
         $matches = null;
         if (!preg_match("/(.*?):(\\d+): (.*?)\$/", $line, $matches)) {
             continue;
         }
         foreach ($matches as $key => $match) {
             $matches[$key] = trim($match);
         }
         $code = head(explode(',', $matches[3]));
         $message = new ArcanistLintMessage();
         $message->setPath($path);
         $message->setLine($matches[2]);
         $message->setName($this->getLinterName() . " " . $code);
         $message->setDescription($matches[3]);
         $message->setSeverity($this->getMessageCodeSeverity($code));
         $this->addLintMessage($message);
     }
 }
Exemplo n.º 4
0
/**
 * @group xhpast
 */
function xhpast_get_parser_future($data)
{
    if (!xhpast_is_available()) {
        throw new Exception(xhpast_get_build_instructions());
    }
    $future = new ExecFuture('%s', xhpast_get_binary_path());
    $future->write($data);
    return $future;
}
 /**
  * Construct an exec channel from a @{class:ExecFuture}. The future should
  * **NOT** have been started yet (e.g., with `isReady()` or `start()`),
  * because @{class:ExecFuture} closes stdin by default when futures start.
  * If stdin has been closed, you will be unable to write on the channel.
  *
  * @param ExecFuture Future to use as an underlying I/O source.
  * @task construct
  */
 public function __construct(ExecFuture $future)
 {
     // Make an empty write to keep the stdin pipe open. By default, futures
     // close this pipe when they start.
     $future->write('', $keep_pipe = true);
     // Start the future so that reads and writes work immediately.
     $future->isReady();
     $this->future = $future;
 }
 private function writeAndRead($write, $read)
 {
     $future = new ExecFuture('cat');
     $future->write($write);
     $lines = array();
     foreach (new LinesOfALargeExecFuture($future) as $line) {
         $lines[] = $line;
     }
     $this->assertEqual($read, $lines, pht('Write: %s', id(new PhutilUTF8StringTruncator())->setMaximumGlyphs(32)->truncateString($write)));
 }
 private function writeAndRead($write, $read)
 {
     $future = new ExecFuture('cat');
     $future->write($write);
     $lines = array();
     foreach (new LinesOfALargeExecFuture($future) as $line) {
         $lines[] = $line;
     }
     $this->assertEqual($read, $lines, "Write: " . phutil_utf8_shorten($write, 32));
 }
 private function runBootloaderTests(PhageAgentBootloader $boot)
 {
     $name = get_class($boot);
     $exec = new ExecFuture('%C', $boot->getBootCommand());
     $exec->write($boot->getBootSequence(), $keep_open = true);
     $exec_channel = new PhutilExecChannel($exec);
     $agent = new PhutilJSONProtocolChannel($exec_channel);
     $agent->write(array('type' => 'EXEC', 'key' => 1, 'command' => 'echo phage'));
     $this->agentExpect($agent, array('type' => 'RSLV', 'key' => 1, 'err' => 0, 'stdout' => "phage\n", 'stderr' => ''), "'echo phage' for {$name}");
     $agent->write(array('type' => 'EXIT'));
 }
 public function getHighlightFuture($source)
 {
     $language = idx($this->config, 'language');
     if ($language) {
         $language = $this->getPygmentsLexerNameFromLanguageName($language);
         $future = new ExecFuture('pygmentize -O stripnl=False -f html -l %s', $language);
         $future->write($source);
         return new PhutilDefaultSyntaxHighlighterEnginePygmentsFuture($future, $source);
     }
     return id(new PhutilDefaultSyntaxHighlighter())->getHighlightFuture($source);
 }
 /**
  * @phutil-external-symbol function jsShrink
  */
 public function transformResource($path, $data)
 {
     $type = self::getResourceType($path);
     switch ($type) {
         case 'css':
             $data = $this->replaceCSSPrintRules($path, $data);
             $data = $this->replaceCSSVariables($path, $data);
             $data = preg_replace_callback('@url\\s*\\((\\s*[\'"]?.*?)\\)@s', nonempty($this->translateURICallback, array($this, 'translateResourceURI')), $data);
             break;
     }
     if (!$this->minify) {
         return $data;
     }
     // Some resources won't survive minification (like Raphael.js), and are
     // marked so as not to be minified.
     if (strpos($data, '@' . 'do-not-minify') !== false) {
         return $data;
     }
     switch ($type) {
         case 'css':
             // Remove comments.
             $data = preg_replace('@/\\*.*?\\*/@s', '', $data);
             // Remove whitespace around symbols.
             $data = preg_replace('@\\s*([{}:;,])\\s*@', '\\1', $data);
             // Remove unnecessary semicolons.
             $data = preg_replace('@;}@', '}', $data);
             // Replace #rrggbb with #rgb when possible.
             $data = preg_replace('@#([a-f0-9])\\1([a-f0-9])\\2([a-f0-9])\\3@i', '#\\1\\2\\3', $data);
             $data = trim($data);
             break;
         case 'js':
             // If `jsxmin` is available, use it. jsxmin is the Javelin minifier and
             // produces the smallest output, but is complicated to build.
             if (Filesystem::binaryExists('jsxmin')) {
                 $future = new ExecFuture('jsxmin __DEV__:0');
                 $future->write($data);
                 list($err, $result) = $future->resolve();
                 if (!$err) {
                     $data = $result;
                     break;
                 }
             }
             // If `jsxmin` is not available, use `JsShrink`, which doesn't compress
             // quite as well but is always available.
             $root = dirname(phutil_get_library_root('phabricator'));
             require_once $root . '/externals/JsShrink/jsShrink.php';
             $data = jsShrink($data);
             break;
     }
     return $data;
 }
Exemplo n.º 11
0
 public function __construct($sockname, $repo_root, $args, array $command)
 {
     $this->command = json_encode($command);
     $console = PhutilConsole::getConsole();
     $console->writeLog("cli query: %s\n", $this->command);
     $future = new ExecFuture("%C {$args} -U %s %s %s %s %s", "{$repo_root}/watchman", $sockname, '--no-pretty', '--no-spawn', '--no-local', '-j');
     $cwd = getcwd();
     if (!$cwd) {
         throw new Exception("can't figure out my cwd!?");
     }
     $future->setCWD($cwd);
     $future->write($this->command . "\n");
     parent::__construct($future);
 }
Exemplo n.º 12
0
 /**
  * Constructs an @{class:ExecFuture} for XHPAST.
  *
  * @param  wild        Data to pass to the future.
  * @return ExecFuture
  */
 public static function getParserFuture($data)
 {
     if (!self::isAvailable()) {
         try {
             // Try to build XHPAST automatically. If we can't then just ask the
             // user to build it themselves.
             self::build();
         } catch (CommandException $ex) {
             throw new PhutilProxyException(self::getBuildInstructions(), $ex);
         }
     }
     $future = new ExecFuture('%s', self::getPath());
     $future->write($data);
     return $future;
 }
Exemplo n.º 13
0
/**
 * @group xhpast
 */
function xhpast_get_parser_future($data)
{
    if (!xhpast_is_available()) {
        try {
            // Try to build XHPAST automatically. If we can't then just ask the user
            // to build it themselves.
            xhpast_build();
        } catch (CommandException $e) {
            throw new Exception(xhpast_get_build_instructions());
        }
    }
    $future = new ExecFuture('%s', xhpast_get_binary_path());
    $future->write($data);
    return $future;
}
 public function getHighlightFuture($source)
 {
     $language = idx($this->config, 'language');
     if ($language) {
         $language = $this->getPygmentsLexerNameFromLanguageName($language);
         $future = new ExecFuture('pygmentize -O encoding=utf-8 -O stripnl=False -f html -l %s', $language);
         $scrub = false;
         if ($language == 'php' && strpos($source, '<?') === false) {
             $source = "<?php\n" . $source;
             $scrub = true;
         }
         $future->write($source);
         return new PhutilDefaultSyntaxHighlighterEnginePygmentsFuture($future, $source, $scrub);
     }
     return id(new PhutilDefaultSyntaxHighlighter())->getHighlightFuture($source);
 }
Exemplo n.º 15
0
 public function willParseFiles(array $file_map)
 {
     $root = dirname(phutil_get_library_root('javelin-diviner'));
     $bin = $root . '/jsast/jsast';
     if (!Filesystem::pathExists($bin)) {
         throw new Exception("You must build the 'jsast' binary before you can generate " . "Javelin documentation.");
     }
     $futures = array();
     foreach ($file_map as $file => $data) {
         $future = new ExecFuture($bin);
         $future->write($data);
         $futures[$file] = $future;
     }
     foreach (Futures($futures)->limit(8) as $file => $future) {
         $this->trees[$file] = $future->resolveJSON();
     }
 }
 public function transformResource($path, $data)
 {
     $type = self::getResourceType($path);
     switch ($type) {
         case 'css':
             $data = preg_replace_callback('@url\\s*\\((\\s*[\'"]?/rsrc/.*?)\\)@s', array($this, 'translateResourceURI'), $data);
             break;
     }
     if (!$this->minify) {
         return $data;
     }
     // Some resources won't survive minification (like Raphael.js), and are
     // marked so as not to be minified.
     if (strpos($data, '@' . 'do-not-minify') !== false) {
         return $data;
     }
     switch ($type) {
         case 'css':
             // Remove comments.
             $data = preg_replace('@/\\*.*?\\*/@s', '', $data);
             // Remove whitespace around symbols.
             $data = preg_replace('@\\s*([{}:;,])\\s*@', '\\1', $data);
             // Remove unnecessary semicolons.
             $data = preg_replace('@;}@', '}', $data);
             // Replace #rrggbb with #rgb when possible.
             $data = preg_replace('@#([a-f0-9])\\1([a-f0-9])\\2([a-f0-9])\\3@i', '#\\1\\2\\3', $data);
             $data = trim($data);
             break;
         case 'js':
             $root = dirname(phutil_get_library_root('phabricator'));
             $bin = $root . '/externals/javelin/support/jsxmin/jsxmin';
             if (@file_exists($bin)) {
                 $future = new ExecFuture("{$bin} __DEV__:0");
                 $future->write($data);
                 list($err, $result) = $future->resolve();
                 if (!$err) {
                     $data = $result;
                 }
             }
             break;
     }
     return $data;
 }
 public function lintPath($path)
 {
     $flake8_bin = $this->getFlake8Path();
     $options = $this->getFlake8Options();
     $f = new ExecFuture("%C %C -", $flake8_bin, $options);
     $f->write($this->getData($path));
     list($err, $stdout, $stderr) = $f->resolve();
     if ($err === 2) {
         throw new Exception("flake8 failed to run correctly:\n" . $stderr);
     }
     $lines = explode("\n", $stdout);
     $messages = array();
     foreach ($lines as $line) {
         $matches = null;
         // stdin:2: W802 undefined name 'foo'  # pyflakes
         // stdin:3:1: E302 expected 2 blank lines, found 1  # pep8
         if (!preg_match('/^(.*?):(\\d+):(?:(\\d+):)? (\\S+) (.*)$/', $line, $matches)) {
             continue;
         }
         foreach ($matches as $key => $match) {
             $matches[$key] = trim($match);
         }
         if (substr($matches[4], 0, 1) == 'E') {
             $severity = ArcanistLintSeverity::SEVERITY_ERROR;
         } else {
             $severity = ArcanistLintSeverity::SEVERITY_WARNING;
         }
         $message = new ArcanistLintMessage();
         $message->setPath($path);
         $message->setLine($matches[2]);
         if (!empty($matches[3])) {
             $message->setChar($matches[3]);
         }
         $message->setCode($matches[4]);
         $message->setName($this->getLinterName() . ' ' . $matches[3]);
         $message->setDescription($matches[5]);
         $message->setSeverity($severity);
         $this->addLintMessage($message);
     }
 }
 public function getHighlightFuture($source)
 {
     $language = idx($this->config, 'language');
     if (preg_match('/\\r(?!\\n)/', $source)) {
         // TODO: Pygments converts "\r" newlines into "\n" newlines, so we can't
         // use it on files with "\r" newlines. If we have "\r" not followed by
         // "\n" in the file, skip highlighting.
         $language = null;
     }
     if ($language) {
         $language = $this->getPygmentsLexerNameFromLanguageName($language);
         $future = new ExecFuture('pygmentize -O encoding=utf-8 -O stripnl=False -f html -l %s', $language);
         $scrub = false;
         if ($language == 'php' && strpos($source, '<?') === false) {
             $source = "<?php\n" . $source;
             $scrub = true;
         }
         $future->write($source);
         return new PhutilDefaultSyntaxHighlighterEnginePygmentsFuture($future, $source, $scrub);
     }
     return id(new PhutilDefaultSyntaxHighlighter())->getHighlightFuture($source);
 }
Exemplo n.º 19
0
 public static function rebuildPackages($root)
 {
     $packages = JavelinSyncSpec::getPackageMap();
     $data = array();
     foreach ($packages as $package => $items) {
         $content = array();
         foreach ($items as $item) {
             if (empty($data[$item])) {
                 $data[$item] = Filesystem::readFile($root . '/src/' . $item);
             }
             $content[] = $data[$item];
         }
         $content = implode("\n\n", $content);
         echo "Writing {$package}.dev.js...\n";
         Filesystem::writeFile($root . '/pkg/' . $package . '.dev.js', $content);
         echo "Writing {$package}.min.js...\n";
         $exec = new ExecFuture($root . '/support/jsxmin/jsxmin __DEV__:0');
         $exec->write($content);
         list($stdout) = $exec->resolvex();
         Filesystem::writeFile($root . '/pkg/' . $package . '.min.js', $stdout);
     }
 }
Exemplo n.º 20
0
 public function lintPath($path)
 {
     $this->checkBinaryConfiguration();
     $data = $this->getData($path);
     $future = new ExecFuture('%C', $this->getBinary());
     $future->write($data);
     list($err, $stdout, $stderr) = $future->resolve();
     if (empty($stdout) && $err) {
         throw new Exception(sprintf("%s\n\nSTDOUT\n%s\n\nSTDERR\n%s", pht($this->getLinterName() . ' failed to parse output!'), $stdout, $stderr));
     }
     if ($stdout !== $data) {
         $lines = explode("\n", $data);
         $formatted_lines = explode("\n", $stdout);
         foreach ($lines as $line_idx => $line) {
             if ($line != $formatted_lines[$line_idx]) {
                 $lines = array_slice($lines, $line_idx);
                 $formatted_lines = array_slice($formatted_lines, $line_idx);
                 break;
             }
         }
         $this->raiseLintAtLine($line_idx + 1, 1, self::LINT_GO_UNFORMATTED, pht('%s was not formatted correctly. Please setup your ' . 'editor to run gofmt on save', $path), implode("\n", $lines), implode("\n", $formatted_lines));
     }
 }
 public function markupContent($content, array $argv)
 {
     if (!Filesystem::binaryExists('cowsay')) {
         return $this->markupError(pht('Unable to locate the `%s` binary. Install cowsay.', 'cowsay'));
     }
     $bin = idx($argv, 'think') ? 'cowthink' : 'cowsay';
     $eyes = idx($argv, 'eyes', 'oo');
     $tongue = idx($argv, 'tongue', '  ');
     $cow = idx($argv, 'cow', 'default');
     // NOTE: Strip this aggressively to prevent nonsense like
     // `cow=/etc/passwd`. We could build a whiltelist with `cowsay -l`.
     $cow = preg_replace('/[^a-z.-]+/', '', $cow);
     $future = new ExecFuture('%s -e %s -T %s -f %s ', $bin, $eyes, $tongue, $cow);
     $future->setTimeout(15);
     $future->write($content);
     list($err, $stdout, $stderr) = $future->resolve();
     if ($err) {
         return $this->markupError(pht('Execution of `%s` failed: %s', 'cowsay', $stderr));
     }
     if ($this->getEngine()->isTextMode()) {
         return $stdout;
     }
     return phutil_tag('div', array('class' => 'PhabricatorMonospaced remarkup-cowsay'), $stdout);
 }
Exemplo n.º 22
0
 private function newSymbolsFuture($path)
 {
     $javelinsymbols = $this->getSymbolsBinaryPath();
     $future = new ExecFuture($javelinsymbols . ' # ' . escapeshellarg($path));
     $future->write($this->getData($path));
     return $future;
 }
Exemplo n.º 23
0
 /**
  * Sends mail using the $Sendmail program.
  * @param string $header The message headers
  * @param string $body The message body
  * @access protected
  * @return bool
  */
 protected function SendmailSend($header, $body)
 {
     if ($this->Sender != '') {
         $sendmail = sprintf("%s -oi -f %s -t", escapeshellcmd($this->Sendmail), escapeshellarg($this->Sender));
     } else {
         $sendmail = sprintf("%s -oi -t", escapeshellcmd($this->Sendmail));
     }
     if ($this->SingleTo === true) {
         foreach ($this->SingleToArray as $key => $val) {
             $mail = new ExecFuture('%C', $sendmail);
             $mail->write("To: {$val}\n", true);
             $mail->write($header . $body);
             $mail->resolvex();
         }
     } else {
         $mail = new ExecFuture('%C', $sendmail);
         $mail->write($header . $body);
         $mail->resolvex();
     }
     return true;
 }
Exemplo n.º 24
0
 public function testReadBuffering()
 {
     $str_len_8 = 'abcdefgh';
     $str_len_4 = 'abcd';
     // This is a write/read with no read buffer.
     $future = new ExecFuture('cat');
     $future->write($str_len_8);
     do {
         $future->isReady();
         list($read) = $future->read();
         if (strlen($read)) {
             break;
         }
     } while (true);
     // We expect to get the entire string back in the read.
     $this->assertEqual($str_len_8, $read);
     $future->resolve();
     // This is a write/read with a read buffer.
     $future = new ExecFuture('cat');
     $future->write($str_len_8);
     // Set the read buffer size.
     $future->setReadBufferSize(4);
     do {
         $future->isReady();
         list($read) = $future->read();
         if (strlen($read)) {
             break;
         }
     } while (true);
     // We expect to get the entire string back in the read.
     $this->assertEqual($str_len_4, $read);
     $future->resolve();
 }
 private function executeDaemonLaunchCommand($command, $daemon_script_dir, array $config, $run_as_user = null)
 {
     $is_sudo = false;
     if ($run_as_user) {
         // If anything else besides sudo should be
         // supported then insert it here (runuser, su, ...)
         $command = csprintf('sudo -En -u %s -- %C', $run_as_user, $command);
         $is_sudo = true;
     }
     $future = new ExecFuture('exec %C', $command);
     // Play games to keep 'ps' looking reasonable.
     $future->setCWD($daemon_script_dir);
     $future->write(json_encode($config));
     list($stdout, $stderr) = $future->resolvex();
     if ($is_sudo) {
         // On OSX, `sudo -n` exits 0 when the user does not have permission to
         // switch accounts without a password. This is not consistent with
         // sudo on Linux, and seems buggy/broken. Check for this by string
         // matching the output.
         if (preg_match('/sudo: a password is required/', $stderr)) {
             throw new Exception(pht('sudo exited with a zero exit code, but emitted output ' . 'consistent with failure under OSX.'));
         }
     }
 }
Exemplo n.º 26
0
 private function uploadFile($data, $name, $desc)
 {
     $result = array('guid' => null, 'mime' => null, 'size' => null);
     $result['size'] = $size = strlen($data);
     if (!$size) {
         return $result;
     }
     $future = new ExecFuture('file -b --mime -');
     $future->write($data);
     list($mime_type) = $future->resolvex();
     $mime_type = trim($mime_type);
     $result['mime'] = $mime_type;
     echo "Uploading {$desc} '{$name}' ({$mime_type}, {$size} bytes)...\n";
     try {
         $guid = $this->getConduit()->callMethodSynchronous('file.upload', array('data_base64' => base64_encode($data), 'name' => $name));
         $result['guid'] = $guid;
     } catch (ConduitClientException $e) {
         $message = "Failed to upload {$desc} '{$name}'.  Continue?";
         if (!phutil_console_confirm($message, $default_no = false)) {
             throw new ArcanistUsageException('Aborted due to file upload failure.');
         }
     }
     return $result;
 }
Exemplo n.º 27
0
 protected final function buildFutures(array $paths)
 {
     $executable = $this->getExecutableCommand();
     $bin = csprintf('%C %Ls', $executable, $this->getCommandFlags());
     $futures = array();
     foreach ($paths as $path) {
         if ($this->supportsReadDataFromStdin()) {
             $future = new ExecFuture('%C %C', $bin, $this->getReadDataFromStdinFilename());
             $future->write($this->getEngine()->loadData($path));
         } else {
             // TODO: In commit hook mode, we need to do more handling here.
             $disk_path = $this->getEngine()->getFilePathOnDisk($path);
             $path_argument = $this->getPathArgumentForLinterFuture($disk_path);
             $future = new ExecFuture('%C %C', $bin, $path_argument);
         }
         $future->setCWD($this->getEngine()->getWorkingCopy()->getProjectRoot());
         $futures[$path] = $future;
     }
     return $futures;
 }
Exemplo n.º 28
0
$files = array('core/init.js', 'core/util.js', 'core/install.js', 'core/Event.js', 'core/Stratcom.js', 'lib/behavior.js', 'lib/Request.js', 'lib/Vector.js', 'lib/DOM.js', 'lib/JSON.js', 'lib/Mask.js', 'lib/Workflow.js', 'lib/URI.js', 'lib/control/typeahead/Typeahead.js', 'lib/control/typeahead/source/TypeaheadSource.js', 'lib/control/typeahead/source/TypeaheadPreloadedSource.js', 'lib/control/typeahead/source/TypeaheadOnDemandSource.js', 'lib/control/typeahead/normalizer/TypeaheadNormalizer.js', 'lib/control/tokenizer/Tokenizer.js', 'docs/Base.js');
$packages = array('init' => array('core/init.js'), 'javelin' => array('core/util.js', 'core/install.js', 'core/Event.js', 'core/Stratcom.js', 'lib/behavior.js', 'lib/Request.js', 'lib/Vector.js', 'lib/DOM.js', 'lib/JSON.js', 'lib/URI.js'), 'typeahead' => array('lib/control/typeahead/Typeahead.js', 'lib/control/typeahead/normalizer/TypeaheadNormalizer.js', 'lib/control/typeahead/source/TypeaheadSource.js', 'lib/control/typeahead/source/TypeaheadPreloadedSource.js', 'lib/control/typeahead/source/TypeaheadOnDemandSource.js', 'lib/control/tokenizer/Tokenizer.js'), 'workflow' => array('lib/Mask.js', 'lib/Workflow.js'));
$root = Filesystem::resolvePath($argv[1]) . '/html/js/javelin/';
$data = array();
foreach ($files as $file) {
    echo "Reading {$file}...\n";
    $content = Filesystem::readFile($root . $file);
    // Strip out Facebook-specific bookkeeping code.
    $content = preg_replace("@/\\*\\+([a-z]+)\\*/.*?/\\*-\\1\\*/([ ]*\n)*@s", "\n", $content);
    $data[$file] = $content;
}
$local = dirname(dirname(__FILE__));
foreach ($data as $file => $content) {
    echo "Writing {$file}...\n";
    execx('mkdir -p %s', $local . '/src/' . dirname($file));
    Filesystem::writeFile($local . '/src/' . $file, $content);
}
foreach ($packages as $package => $items) {
    $content = array();
    foreach ($items as $item) {
        $content[] = $data[$item];
    }
    $content = implode("\n\n", $content);
    echo "Writing {$package}.dev.js...\n";
    Filesystem::writeFile($local . '/pkg/' . $package . '.dev.js', $content);
    echo "Writing {$package}.min.js...\n";
    $exec = new ExecFuture($local . '/support/jsxmin/jsxmin __DEV__:0');
    $exec->write($content);
    list($stdout) = $exec->resolvex();
    Filesystem::writeFile($local . '/pkg/' . $package . '.min.js', $stdout);
}
 private function newSymbolsFuture($path)
 {
     $future = new ExecFuture('javelinsymbols # %s', $path);
     $future->write($this->getData($path));
     return $future;
 }
 public function run()
 {
     $this->console = PhutilConsole::getConsole();
     $this->runRepositoryAPISetup();
     if ($this->getArgument('no-diff')) {
         $this->removeScratchFile('diff-result.json');
         $data = $this->runLintUnit();
         $this->writeScratchJSONFile('diff-result.json', $data);
         return 0;
     }
     $this->runDiffSetupBasics();
     $background = $this->getArgument('background', true);
     if ($this->isRawDiffSource() || phutil_is_windows()) {
         $background = false;
     }
     if ($background) {
         $argv = $this->getPassedArguments();
         if (!PhutilConsoleFormatter::getDisableANSI()) {
             array_unshift($argv, '--ansi');
         }
         $script = phutil_get_library_root('arcanist') . '/../scripts/arcanist.php';
         if ($argv) {
             $lint_unit = new ExecFuture('php %s --recon diff --no-diff %Ls', $script, $argv);
         } else {
             $lint_unit = new ExecFuture('php %s --recon diff --no-diff', $script);
         }
         $lint_unit->write('', true);
         $lint_unit->start();
     }
     $commit_message = $this->buildCommitMessage();
     $this->dispatchEvent(ArcanistEventType::TYPE_DIFF_DIDBUILDMESSAGE, array('message' => $commit_message));
     if (!$this->shouldOnlyCreateDiff()) {
         $revision = $this->buildRevisionFromCommitMessage($commit_message);
     }
     if ($background) {
         $server = new PhutilConsoleServer();
         $server->addExecFutureClient($lint_unit);
         $server->setHandler(array($this, 'handleServerMessage'));
         $server->run();
         list($err) = $lint_unit->resolve();
         $data = $this->readScratchJSONFile('diff-result.json');
         if ($err || !$data) {
             throw new Exception('Unable to read results from background linting and unit testing. ' . 'You can try running arc diff again with --background 0');
         }
     } else {
         $server = $this->console->getServer();
         $server->setHandler(array($this, 'handleServerMessage'));
         $data = $this->runLintUnit();
     }
     $lint_result = $data['lintResult'];
     $this->unresolvedLint = $data['unresolvedLint'];
     $this->postponedLinters = $data['postponedLinters'];
     $unit_result = $data['unitResult'];
     $this->testResults = $data['testResults'];
     if ($this->getArgument('nolint')) {
         $this->excuses['lint'] = $this->getSkipExcuse('Provide explanation for skipping lint or press Enter to abort:', 'lint-excuses');
     }
     if ($this->getArgument('nounit')) {
         $this->excuses['unit'] = $this->getSkipExcuse('Provide explanation for skipping unit tests or press Enter to abort:', 'unit-excuses');
     }
     $changes = $this->generateChanges();
     if (!$changes) {
         throw new ArcanistUsageException("There are no changes to generate a diff from!");
     }
     $diff_spec = array('changes' => mpull($changes, 'toDictionary'), 'lintStatus' => $this->getLintStatus($lint_result), 'unitStatus' => $this->getUnitStatus($unit_result)) + $this->buildDiffSpecification();
     $conduit = $this->getConduit();
     $diff_info = $conduit->callMethodSynchronous('differential.creatediff', $diff_spec);
     $this->diffID = $diff_info['diffid'];
     $event = $this->dispatchEvent(ArcanistEventType::TYPE_DIFF_WASCREATED, array('diffID' => $diff_info['diffid'], 'lintResult' => $lint_result, 'unitResult' => $unit_result));
     $this->updateLintDiffProperty();
     $this->updateUnitDiffProperty();
     $this->updateLocalDiffProperty();
     $this->resolveDiffPropertyUpdates();
     $output_json = $this->getArgument('json');
     if ($this->shouldOnlyCreateDiff()) {
         if (!$output_json) {
             echo phutil_console_format("Created a new Differential diff:\n" . "        **Diff URI:** __%s__\n\n", $diff_info['uri']);
         } else {
             $human = ob_get_clean();
             echo json_encode(array('diffURI' => $diff_info['uri'], 'diffID' => $this->getDiffID(), 'human' => $human)) . "\n";
             ob_start();
         }
     } else {
         $revision['diffid'] = $this->getDiffID();
         if ($commit_message->getRevisionID()) {
             $result = $conduit->callMethodSynchronous('differential.updaterevision', $revision);
             foreach (array('edit-messages.json', 'update-messages.json') as $file) {
                 $messages = $this->readScratchJSONFile($file);
                 unset($messages[$revision['id']]);
                 $this->writeScratchJSONFile($file, $messages);
             }
             echo "Updated an existing Differential revision:\n";
         } else {
             $revision = $this->dispatchWillCreateRevisionEvent($revision);
             $result = $conduit->callMethodSynchronous('differential.createrevision', $revision);
             $revised_message = $conduit->callMethodSynchronous('differential.getcommitmessage', array('revision_id' => $result['revisionid']));
             if ($this->shouldAmend()) {
                 $repository_api = $this->getRepositoryAPI();
                 if ($repository_api->supportsAmend()) {
                     echo "Updating commit message...\n";
                     $repository_api->amendCommit($revised_message);
                 } else {
                     echo "Commit message was not amended. Amending commit message is " . "only supported in git and hg (version 2.2 or newer)";
                 }
             }
             echo "Created a new Differential revision:\n";
         }
         $uri = $result['uri'];
         echo phutil_console_format("        **Revision URI:** __%s__\n\n", $uri);
         if ($this->getArgument('plan-changes')) {
             $conduit->callMethodSynchronous('differential.createcomment', array('revision_id' => $result['revisionid'], 'action' => 'rethink'));
             echo "Planned changes to the revision.\n";
         }
     }
     echo "Included changes:\n";
     foreach ($changes as $change) {
         echo '  ' . $change->renderTextSummary() . "\n";
     }
     if ($output_json) {
         ob_get_clean();
     }
     $this->removeScratchFile('create-message');
     return 0;
 }