Example #1
0
 function testMoveReAdd()
 {
     if (PHP_OS == 'Linux' && getenv('TRAVIS')) {
         $this->assertSkipped('openvz and inotify unlinks == bad time');
     }
     $dir = new WatchmanDirectoryFixture();
     $root = $dir->getPath();
     mkdir("{$root}/foo");
     $watch = $this->watch($root);
     $this->assertFileListUsingSince($root, 'n:foo', array('foo'), array('foo'));
     $this->watchmanCommand('log', 'debug', 'XXX: touch foo/222');
     touch("{$root}/foo/222");
     $this->assertFileListUsingSince($root, 'n:foo', array('foo', 'foo/222'), array('foo/222'));
     $this->watchmanCommand('log', 'debug', 'XXX: mkdir foo/bar');
     mkdir("{$root}/foo/bar");
     $since = array('foo/bar');
     if (PHP_OS == 'SunOS' || phutil_is_windows()) {
         // This makes me sad, but Solaris reports the parent dir
         // as changed when we mkdir within it
         array_unshift($since, 'foo');
     }
     $this->assertFileListUsingSince($root, 'n:foo', array('foo', 'foo/222', 'foo/bar'), $since);
     $this->watchmanCommand('log', 'debug', 'XXX: rmdir foo/bar');
     rmdir("{$root}/foo/bar");
     $this->watchmanCommand('log', 'debug', 'XXX: unlink foo/222');
     unlink("{$root}/foo/222");
     $this->watchmanCommand('log', 'debug', 'XXX: rmdir foo');
     rmdir("{$root}/foo");
     $this->assertFileListUsingSince($root, 'n:foo', array(), array());
     $this->watchmanCommand('log', 'debug', 'XXX: mkdir foo');
     mkdir("{$root}/foo");
     $this->watchmanCommand('log', 'debug', 'XXX: touch foo/222');
     touch("{$root}/foo/222");
     $this->assertFileListUsingSince($root, 'n:foo', array("foo", "foo/222"), array("foo", "foo/222"));
 }
 /**
  * Execute this command.
  *
  * @return int  Error code returned by the subprocess.
  *
  * @task command
  */
 public function execute()
 {
     $command = $this->command;
     $profiler = PhutilServiceProfiler::getInstance();
     $call_id = $profiler->beginServiceCall(array('type' => 'exec', 'subtype' => 'passthru', 'command' => $command));
     $spec = array(STDIN, STDOUT, STDERR);
     $pipes = array();
     if ($command instanceof PhutilCommandString) {
         $unmasked_command = $command->getUnmaskedString();
     } else {
         $unmasked_command = $command;
     }
     $env = $this->env;
     $cwd = $this->cwd;
     $options = array();
     if (phutil_is_windows()) {
         // Without 'bypass_shell', things like launching vim don't work properly,
         // and we can't execute commands with spaces in them, and all commands
         // invoked from git bash fail horridly, and everything is a mess in
         // general.
         $options['bypass_shell'] = true;
     }
     $trap = new PhutilErrorTrap();
     $proc = @proc_open($unmasked_command, $spec, $pipes, $cwd, $env, $options);
     $errors = $trap->getErrorsAsString();
     $trap->destroy();
     if (!is_resource($proc)) {
         throw new Exception(pht('Failed to passthru %s: %s', 'proc_open()', $errors));
     }
     $err = proc_close($proc);
     $profiler->endServiceCall($call_id, array('err' => $err));
     return $err;
 }
/**
 * @group xhpast
 */
function xhpast_get_binary_path()
{
    if (phutil_is_windows()) {
        return dirname(__FILE__) . '\\xhpast.exe';
    }
    return dirname(__FILE__) . '/xhpast';
}
Example #4
0
 function catCommand()
 {
     if (!phutil_is_windows()) {
         return array('cat');
     }
     return array(PHP_BINARY, '-d register_argc_argv=1', dirname(__FILE__) . DIRECTORY_SEPARATOR . '_cat.php');
 }
Example #5
0
 public function getLocalCommitInformation()
 {
     if ($this->repositoryHasNoCommits) {
         // Zero commits.
         throw new Exception("You can't get local commit information for a repository with no " . "commits.");
     } else {
         if ($this->relativeCommit == self::GIT_MAGIC_ROOT_COMMIT) {
             // One commit.
             $against = 'HEAD';
         } else {
             // 2..N commits.
             $against = $this->getRelativeCommit() . '..HEAD';
         }
     }
     // NOTE: Windows escaping of "%" symbols apparently is inherently broken;
     // when passed throuhgh escapeshellarg() they are replaced with spaces.
     // TODO: Learn how cmd.exe works and find some clever workaround?
     // NOTE: If we use "%x00", output is truncated in Windows.
     list($info) = $this->execxLocal(phutil_is_windows() ? 'log %s --format=%C --' : 'log %s --format=%s --', $against, '%H%x01%T%x01%P%x01%at%x01%an%x01%s');
     $commits = array();
     $info = trim($info);
     $info = explode("\n", $info);
     foreach ($info as $line) {
         list($commit, $tree, $parents, $time, $author, $title) = explode("", $line, 6);
         $commits[] = array('commit' => $commit, 'tree' => $tree, 'parents' => array_filter(explode(' ', $parents)), 'time' => $time, 'author' => $author, 'summary' => $title);
     }
     return $commits;
 }
Example #6
0
/**
 * Execute a command which takes over stdin, stdout and stderr, similar to
 * passthru(), but which preserves TTY semantics, escapes arguments, and is
 * traceable.
 *
 * @param  string  sprintf()-style command pattern to execute.
 * @param  ...     Arguments to sprintf pattern.
 * @return int     Return code.
 * @group exec
 */
function phutil_passthru($cmd)
{
    $args = func_get_args();
    $command = call_user_func_array('csprintf', $args);
    $profiler = PhutilServiceProfiler::getInstance();
    $call_id = $profiler->beginServiceCall(array('type' => 'exec', 'subtype' => 'passthru', 'command' => $command));
    $spec = array(STDIN, STDOUT, STDERR);
    $pipes = array();
    if (phutil_is_windows()) {
        // Without 'bypass_shell', things like launching vim don't work properly,
        // and we can't execute commands with spaces in them, and all commands
        // invoked from git bash fail horridly, and everything is a mess in general.
        $options = array('bypass_shell' => true);
        $proc = @proc_open($command, $spec, $pipes, null, null, $options);
    } else {
        $proc = @proc_open($command, $spec, $pipes);
    }
    if ($proc === false) {
        $err = 1;
    } else {
        $err = proc_close($proc);
    }
    $profiler->endServiceCall($call_id, array('err' => $err));
    return $err;
}
Example #7
0
 function testFields()
 {
     $dir = new WatchmanDirectoryFixture();
     $root = $dir->getPath();
     $watch = $this->watch($root);
     $this->assertFileList($root, array());
     $this->watchmanCommand('log', 'debug', 'XXX: touch a');
     touch("{$root}/a");
     $this->assertFileList($root, array('a'));
     $query = $this->watchmanCommand('query', $root, array('fields' => array('name', 'exists', 'new', 'size', 'mode', 'uid', 'gid', 'mtime', 'mtime_ms', 'mtime_us', 'mtime_ns', 'mtime_f', 'ctime', 'ctime_ms', 'ctime_us', 'ctime_ns', 'ctime_f', 'ino', 'dev', 'nlink', 'oclock', 'cclock'), 'since' => 'n:foo'));
     $this->assertEqual(null, idx($query, 'error'));
     $this->assertEqual(1, count($query['files']));
     $file = $query['files'][0];
     $this->assertEqual('a', $file['name']);
     $this->assertEqual(true, $file['exists']);
     $this->assertEqual(true, $file['new']);
     $stat = stat("{$root}/a");
     $compare_fields = array('size', 'mode', 'uid', 'gid', 'nlink');
     if (!phutil_is_windows()) {
         // These are meaningless in msvcrt, so no sense in comparing them
         $compare_fields[] = 'dev';
         $compare_fields[] = 'ino';
     }
     foreach ($compare_fields as $field) {
         $this->assertEqual($stat[$field], $file[$field], $field);
     }
     $time_fields = array('mtime', 'ctime');
     foreach ($time_fields as $field) {
         $this->assertTimeEqual($stat[$field], $file[$field], $file[$field . '_ms'], $file[$field . '_us'], $file[$field . '_ns'], $file[$field . '_f']);
     }
     $this->assertRegex('/^c:\\d+:\\d+:\\d+:\\d+$/', $file['cclock'], "cclock looks clocky");
     $this->assertRegex('/^c:\\d+:\\d+:\\d+:\\d+$/', $file['oclock'], "oclock looks clocky");
 }
 public function testPasswords()
 {
     // Normal "%s" doesn't do anything special.
     $command = csprintf('echo %s', 'hunter2trustno1');
     $this->assertTrue(strpos($command, 'hunter2trustno1') !== false);
     // "%P" takes a PhutilOpaqueEnvelope.
     $caught = null;
     try {
         csprintf('echo %P', 'hunter2trustno1');
     } catch (Exception $ex) {
         $caught = $ex;
     }
     $this->assertTrue($caught instanceof Exception);
     // "%P" masks the provided value.
     $command = csprintf('echo %P', new PhutilOpaqueEnvelope('hunter2trustno1'));
     $this->assertFalse(strpos($command, 'hunter2trustno1'));
     // Executing the command works as expected.
     list($out) = execx('%C', $command);
     $this->assertTrue(strpos($out, 'hunter2trustno1') !== false);
     // Escaping should be robust even when used to escape commands which take
     // other commands.
     if (!phutil_is_windows()) {
         list($out) = execx('sh -c %s', csprintf('sh -c %s', csprintf('sh -c %s', csprintf('echo %P', new PhutilOpaqueEnvelope('!@#$%^&*()')))));
         $this->assertTrue(strpos($out, '!@#$%^&*()') !== false);
     }
 }
 /**
  * Returns the path to the XHPAST binary.
  *
  * @return string
  */
 public static function getPath()
 {
     if (phutil_is_windows()) {
         return dirname(__FILE__) . '\\xhpast.exe';
     }
     return dirname(__FILE__) . '/xhpast';
 }
Example #10
0
 function testSlash()
 {
     if (phutil_is_windows()) {
         $this->assertSkipped("N/A for Windows");
     }
     $res = $this->watch('/', false);
     $this->assertEqual('unable to resolve root /: cannot watch "/"', idx($res, 'error'));
 }
 /**
  * Return the canonical parent directory for a path. Note, returns "/" when
  * passed "/".
  *
  * @param string Some repository path.
  * @return string That path's canonical parent directory.
  * @task pathutil
  */
 public static function getParentPath($path)
 {
     $path = self::normalizePath($path);
     $path = dirname($path);
     if (phutil_is_windows() && $path == '\\') {
         $path = '/';
     }
     return $path;
 }
 private function raiseWarning($bin, $message)
 {
     if (phutil_is_windows()) {
         $preamble = pht("The '%s' binary could not be found. Set the webserver's %s " . "environmental variable to include the directory where it resides, or " . "add that directory to '%s' in the Phabricator configuration.", $bin, 'PATH', 'environment.append-paths');
     } else {
         $preamble = pht("The '%s' binary could not be found. Symlink it into '%s', or set the " . "webserver's %s environmental variable to include the directory where " . "it resides, or add that directory to '%s' in the Phabricator " . "configuration.", $bin, 'phabricator/support/bin/', 'PATH', 'environment.append-paths');
     }
     $this->newIssue('bin.' . $bin)->setShortName(pht("'%s' Missing", $bin))->setName(pht("Missing '%s' Binary", $bin))->setSummary(pht("The '%s' binary could not be located or executed.", $bin))->setMessage($preamble . ' ' . $message)->addPhabricatorConfig('environment.append-paths');
 }
 public function getOptions()
 {
     if (phutil_is_windows()) {
         $paths = array();
     } else {
         $paths = array('/bin', '/usr/bin', '/usr/local/bin');
     }
     $path = getenv('PATH');
     return array($this->newOption('phabricator.base-uri', 'string', null)->setLocked(true)->setSummary(pht('URI where Phabricator is installed.'))->setDescription(pht('Set the URI where Phabricator is installed. Setting this ' . 'improves security by preventing cookies from being set on other ' . 'domains, and allows daemons to send emails with links that have ' . 'the correct domain.'))->addExample('http://phabricator.example.com/', pht('Valid Setting')), $this->newOption('phabricator.production-uri', 'string', null)->setSummary(pht('Primary install URI, for multi-environment installs.'))->setDescription(pht('If you have multiple Phabricator environments (like a ' . 'development/staging environment for working on testing ' . 'Phabricator, and a production environment for deploying it), ' . 'set the production environment URI here so that emails and other ' . 'durable URIs will always generate with links pointing at the ' . 'production environment. If unset, defaults to ' . '{{phabricator.base-uri}}. Most installs do not need to set ' . 'this option.'))->addExample('http://phabricator.example.com/', pht('Valid Setting')), $this->newOption('phabricator.allowed-uris', 'list<string>', array())->setLocked(true)->setSummary(pht('Alternative URIs that can access Phabricator.'))->setDescription(pht("These alternative URIs will be able to access 'normal' pages " . "on your Phabricator install. Other features such as OAuth " . "won't work. The major use case for this is moving installs " . "across domains."))->addExample("http://phabricator2.example.com/\n" . "http://phabricator3.example.com/", pht('Valid Setting')), $this->newOption('phabricator.timezone', 'string', null)->setSummary(pht('The timezone Phabricator should use.'))->setDescription(pht("PHP requires that you set a timezone in your php.ini before " . "using date functions, or it will emit a warning. If this isn't " . "possible (for instance, because you are using HPHP) you can set " . "some valid constant for date_default_timezone_set() here and " . "Phabricator will set it on your behalf, silencing the warning."))->addExample('America/New_York', pht('US East (EDT)'))->addExample('America/Chicago', pht('US Central (CDT)'))->addExample('America/Boise', pht('US Mountain (MDT)'))->addExample('America/Los_Angeles', pht('US West (PDT)')), $this->newOption('phabricator.cookie-prefix', 'string', null)->setSummary(pht('Set a string Phabricator should use to prefix ' . 'cookie names'))->setDescription(pht('Cookies set for x.com are also sent for y.x.com. Assuming ' . 'Phabricator instances are running on both domains, this will ' . 'create a collision preventing you from logging in.'))->addExample('dev', pht('Prefix cookie with "dev"')), $this->newOption('phabricator.show-beta-applications', 'bool', false)->setBoolOptions(array(pht('Install Beta Applications'), pht('Uninstall Beta Applications')))->setSummary(pht('Install applications which are still under development.'))->setDescription(pht("Phabricator includes 'Beta' applications which are in an early " . "stage of development. They range from very rough prototypes to " . "relatively complete (but unpolished) applications.\n\n" . "By default, Beta applications are not installed. You can enable " . "this option to install them if you're interested in previewing " . "upcoming features.\n\n" . "After enabling Beta applications, you can selectively uninstall " . "them (like normal applications).")), $this->newOption('phabricator.serious-business', 'bool', false)->setBoolOptions(array(pht('Serious business'), pht('Shenanigans')))->setSummary(pht('Allows you to remove levity and jokes from the UI.'))->setDescription(pht('By default, Phabricator includes some flavor text in the UI, ' . 'like a prompt to "Weigh In" rather than "Add Comment" in ' . 'Maniphest. If you\'d prefer more traditional UI strings like ' . '"Add Comment", you can set this flag to disable most of the ' . 'extra flavor.')), $this->newOption('remarkup.ignored-object-names', 'string', '/^(Q|V)\\d$/')->setSummary(pht('Text values that match this regex and are also object names ' . 'will not be linked.'))->setDescription(pht('By default, Phabricator links object names in Remarkup fields ' . 'to the corresponding object. This regex can be used to modify ' . 'this behavior; object names that match this regex will not be ' . 'linked.')), $this->newOption('environment.append-paths', 'list<string>', $paths)->setSummary(pht('These paths get appended to your \\$PATH envrionment variable.'))->setDescription(pht("Phabricator occasionally shells out to other binaries on the " . "server. An example of this is the `pygmentize` command, used " . "to syntax-highlight code written in languages other than PHP. " . "By default, it is assumed that these binaries are in the \$PATH " . "of the user running Phabricator (normally 'apache', 'httpd', or " . "'nobody'). Here you can add extra directories to the \$PATH " . "environment variable, for when these binaries are in " . "non-standard locations.\n\n" . "Note that you can also put binaries in " . "`phabricator/support/bin/` (for example, by symlinking them).\n\n" . "The current value of PATH after configuration is applied is:\n\n" . "  lang=text\n" . "  %s", $path))->setLocked(true)->addExample('/usr/local/bin', pht('Add One Path'))->addExample("/usr/bin\n/usr/local/bin", pht('Add Multiple Paths')), $this->newOption('config.lock', 'set', array())->setLocked(true)->setDescription(pht('Additional configuration options to lock.')), $this->newOption('config.hide', 'set', array())->setLocked(true)->setDescription(pht('Additional configuration options to hide.')), $this->newOption('config.mask', 'set', array())->setLocked(true)->setDescription(pht('Additional configuration options to mask.')), $this->newOption('config.ignore-issues', 'set', array())->setLocked(true)->setDescription(pht('Setup issues to ignore.')), $this->newOption('phabricator.env', 'string', null)->setLocked(true)->setDescription(pht('Internal.')), $this->newOption('test.value', 'wild', null)->setLocked(true)->setDescription(pht('Unit test value.')), $this->newOption('phabricator.uninstalled-applications', 'set', array())->setLocked(true)->setDescription(pht('Array containing list of Uninstalled applications.')), $this->newOption('phabricator.application-settings', 'wild', array())->setLocked(true)->setDescription(pht('Customized settings for Phabricator applications.')), $this->newOption('welcome.html', 'string', null)->setLocked(true)->setDescription(pht('Custom HTML to show on the main Phabricator dashboard.')), $this->newOption('phabricator.cache-namespace', 'string', null)->setLocked(true)->setDescription(pht('Cache namespace.')), $this->newOption('phabricator.allow-email-users', 'bool', false)->setBoolOptions(array(pht('Allow'), pht('Disallow')))->setDescription(pht('Allow non-members to interact with tasks over email.')));
 }
Example #14
0
 public function execPassthru($pattern)
 {
     $args = func_get_args();
     if (phutil_is_windows()) {
         $args[0] = 'hg ' . $args[0];
     } else {
         $args[0] = 'HGPLAIN=1 hg ' . $args[0];
     }
     return call_user_func_array('phutil_passthru', $args);
 }
 public function testEscapingIsRobust()
 {
     if (phutil_is_windows()) {
         $this->assertSkipped(pht("This test doesn't work on Windows."));
     }
     // Escaping should be robust even when used to escape commands which take
     // other commands.
     list($out) = execx('sh -c %s', csprintf('sh -c %s', csprintf('sh -c %s', csprintf('echo %P', new PhutilOpaqueEnvelope('!@#$%^&*()')))));
     $this->assertTrue(strpos($out, '!@#$%^&*()') !== false);
 }
 /**
  * Creates a pair of socket channels that are connected to each other. This
  * is mostly useful for writing unit tests of, e.g., protocol channels.
  *
  *   list($x, $y) = PhutilSocketChannel::newChannelPair();
  *
  * @task construct
  */
 public static function newChannelPair()
 {
     $sockets = null;
     $domain = phutil_is_windows() ? STREAM_PF_INET : STREAM_PF_UNIX;
     $pair = stream_socket_pair($domain, STREAM_SOCK_STREAM, STREAM_IPPROTO_IP);
     if (!$pair) {
         throw new Exception("stream_socket_pair() failed!");
     }
     $x = new PhutilSocketChannel($pair[0]);
     $y = new PhutilSocketChannel($pair[1]);
     return array($x, $y);
 }
Example #17
0
function w_unlink($name)
{
    if (phutil_is_windows()) {
        for ($i = 0; $i < 10; $i++) {
            $x = @unlink($name);
            if ($x) {
                return true;
            }
            usleep(200000);
        }
    }
    return unlink($name);
}
 public function getOptions()
 {
     if (phutil_is_windows()) {
         $paths = array();
     } else {
         $paths = array('/bin', '/usr/bin', '/usr/local/bin');
     }
     $path = getenv('PATH');
     $proto_doc_href = PhabricatorEnv::getDoclink('User Guide: Prototype Applications');
     $proto_doc_name = pht('User Guide: Prototype Applications');
     $applications_app_href = '/applications/';
     return array($this->newOption('phabricator.base-uri', 'string', null)->setLocked(true)->setSummary(pht('URI where Phabricator is installed.'))->setDescription(pht('Set the URI where Phabricator is installed. Setting this ' . 'improves security by preventing cookies from being set on other ' . 'domains, and allows daemons to send emails with links that have ' . 'the correct domain.'))->addExample('http://phabricator.example.com/', pht('Valid Setting')), $this->newOption('phabricator.production-uri', 'string', null)->setSummary(pht('Primary install URI, for multi-environment installs.'))->setDescription(pht('If you have multiple Phabricator environments (like a ' . 'development/staging environment for working on testing ' . 'Phabricator, and a production environment for deploying it), ' . 'set the production environment URI here so that emails and other ' . 'durable URIs will always generate with links pointing at the ' . 'production environment. If unset, defaults to `%s`. Most ' . 'installs do not need to set this option.', 'phabricator.base-uri'))->addExample('http://phabricator.example.com/', pht('Valid Setting')), $this->newOption('phabricator.allowed-uris', 'list<string>', array())->setLocked(true)->setSummary(pht('Alternative URIs that can access Phabricator.'))->setDescription(pht("These alternative URIs will be able to access 'normal' pages " . "on your Phabricator install. Other features such as OAuth " . "won't work. The major use case for this is moving installs " . "across domains."))->addExample("http://phabricator2.example.com/\n" . "http://phabricator3.example.com/", pht('Valid Setting')), $this->newOption('phabricator.timezone', 'string', null)->setSummary(pht('The timezone Phabricator should use.'))->setDescription(pht("PHP requires that you set a timezone in your php.ini before " . "using date functions, or it will emit a warning. If this isn't " . "possible (for instance, because you are using HPHP) you can set " . "some valid constant for %s here and Phabricator will set it on " . "your behalf, silencing the warning.", 'date_default_timezone_set()'))->addExample('America/New_York', pht('US East (EDT)'))->addExample('America/Chicago', pht('US Central (CDT)'))->addExample('America/Boise', pht('US Mountain (MDT)'))->addExample('America/Los_Angeles', pht('US West (PDT)')), $this->newOption('phabricator.cookie-prefix', 'string', null)->setLocked(true)->setSummary(pht('Set a string Phabricator should use to prefix cookie names.'))->setDescription(pht('Cookies set for x.com are also sent for y.x.com. Assuming ' . 'Phabricator instances are running on both domains, this will ' . 'create a collision preventing you from logging in.'))->addExample('dev', pht('Prefix cookie with "%s"', 'dev')), $this->newOption('phabricator.show-prototypes', 'bool', false)->setLocked(true)->setBoolOptions(array(pht('Enable Prototypes'), pht('Disable Prototypes')))->setSummary(pht('Install applications which are still under development.'))->setDescription(pht("IMPORTANT: The upstream does not provide support for prototype " . "applications." . "\n\n" . "Phabricator includes prototype applications which are in an " . "**early stage of development**. By default, prototype " . "applications are not installed, because they are often not yet " . "developed enough to be generally usable. You can enable " . "this option to install them if you're developing Phabricator " . "or are interested in previewing upcoming features." . "\n\n" . "To learn more about prototypes, see [[ %s | %s ]]." . "\n\n" . "After enabling prototypes, you can selectively uninstall them " . "(like normal applications).", $proto_doc_href, $proto_doc_name)), $this->newOption('phabricator.serious-business', 'bool', false)->setBoolOptions(array(pht('Serious business'), pht('Shenanigans')))->setSummary(pht('Allows you to remove levity and jokes from the UI.'))->setDescription(pht('By default, Phabricator includes some flavor text in the UI, ' . 'like a prompt to "Weigh In" rather than "Add Comment" in ' . 'Maniphest. If you\'d prefer more traditional UI strings like ' . '"Add Comment", you can set this flag to disable most of the ' . 'extra flavor.')), $this->newOption('remarkup.ignored-object-names', 'string', '/^(Q|V)\\d$/')->setSummary(pht('Text values that match this regex and are also object names ' . 'will not be linked.'))->setDescription(pht('By default, Phabricator links object names in Remarkup fields ' . 'to the corresponding object. This regex can be used to modify ' . 'this behavior; object names that match this regex will not be ' . 'linked.')), $this->newOption('environment.append-paths', 'list<string>', $paths)->setSummary(pht('These paths get appended to your %s environment variable.', '$PATH'))->setDescription(pht("Phabricator occasionally shells out to other binaries on the " . "server. An example of this is the `%s` command, used to " . "syntax-highlight code written in languages other than PHP. By " . "default, it is assumed that these binaries are in the %s of the " . "user running Phabricator (normally 'apache', 'httpd', or " . "'nobody'). Here you can add extra directories to the %s " . "environment variable, for when these binaries are in " . "non-standard locations.\n\n" . "Note that you can also put binaries in `%s` (for example, by " . "symlinking them).\n\n" . "The current value of PATH after configuration is applied is:\n\n" . "  lang=text\n" . "  %s", 'pygmentize', '$PATH', '$PATH', 'phabricator/support/bin/', $path))->setLocked(true)->addExample('/usr/local/bin', pht('Add One Path'))->addExample("/usr/bin\n/usr/local/bin", pht('Add Multiple Paths')), $this->newOption('config.lock', 'set', array())->setLocked(true)->setDescription(pht('Additional configuration options to lock.')), $this->newOption('config.hide', 'set', array())->setLocked(true)->setDescription(pht('Additional configuration options to hide.')), $this->newOption('config.ignore-issues', 'set', array())->setLocked(true)->setDescription(pht('Setup issues to ignore.')), $this->newOption('phabricator.env', 'string', null)->setLocked(true)->setDescription(pht('Internal.')), $this->newOption('test.value', 'wild', null)->setLocked(true)->setDescription(pht('Unit test value.')), $this->newOption('phabricator.uninstalled-applications', 'set', array())->setLocked(true)->setLockedMessage(pht('Use the %s to manage installed applications.', phutil_tag('a', array('href' => $applications_app_href), pht('Applications application'))))->setDescription(pht('Array containing list of uninstalled applications.')), $this->newOption('phabricator.application-settings', 'wild', array())->setLocked(true)->setDescription(pht('Customized settings for Phabricator applications.')), $this->newOption('welcome.html', 'string', null)->setLocked(true)->setDescription(pht('Custom HTML to show on the main Phabricator dashboard.')), $this->newOption('phabricator.cache-namespace', 'string', 'phabricator')->setLocked(true)->setDescription(pht('Cache namespace.')), $this->newOption('phabricator.allow-email-users', 'bool', false)->setBoolOptions(array(pht('Allow'), pht('Disallow')))->setDescription(pht('Allow non-members to interact with tasks over email.')), $this->newOption('phabricator.silent', 'bool', false)->setLocked(true)->setBoolOptions(array(pht('Run Silently'), pht('Run Normally')))->setSummary(pht('Stop Phabricator from sending any email, etc.'))->setDescription(pht('This option allows you to stop Phabricator from sending ' . 'any data to external services. Among other things, it will ' . 'disable email, SMS, repository mirroring, and HTTP hooks.' . "\n\n" . 'This option is intended to allow a Phabricator instance to ' . 'be exported, copied, imported, and run in a test environment ' . 'without impacting users. For example, if you are migrating ' . 'to new hardware, you could perform a test migration first, ' . 'make sure things work, and then do a production cutover ' . 'later with higher confidence and less disruption. Without ' . 'this flag, users would receive duplicate email during the ' . 'time the test instance and old production instance were ' . 'both in operation.')));
 }
 public static function getDisableANSI()
 {
     if (self::$disableANSI === null) {
         if (phutil_is_windows()) {
             self::$disableANSI = true;
         } else {
             if (function_exists('posix_isatty') && !posix_isatty(STDOUT)) {
                 self::$disableANSI = true;
             } else {
                 self::$disableANSI = false;
             }
         }
     }
     return self::$disableANSI;
 }
 public function testResolveBinary()
 {
     // Test to make sure resolveBinary() returns the full path to the `which`
     // and `where` binaries.
     if (phutil_is_windows()) {
         $binary = 'where';
     } else {
         $binary = 'which';
     }
     $path = Filesystem::resolveBinary($binary);
     $this->assertFalse(null === $path);
     $this->assertTrue(file_exists($path));
     $this->assertFalse(is_dir($path));
     $this->assertEqual(null, Filesystem::resolveBinary('halting-problem-decider'));
 }
 public static function getDisableANSI()
 {
     if (self::$disableANSI === null) {
         $term = phutil_utf8_strtolower(getenv("TERM"));
         if (phutil_is_windows() && $term !== "cygwin" && $term !== "ansi") {
             self::$disableANSI = true;
         } else {
             if (function_exists('posix_isatty') && !posix_isatty(STDOUT)) {
                 self::$disableANSI = true;
             } else {
                 self::$disableANSI = false;
             }
         }
     }
     return self::$disableANSI;
 }
Example #22
0
 function testEvenMoreMoves()
 {
     if (phutil_is_windows()) {
         $this->assertSkipped("no unix userland on windows");
     }
     $dir = new WatchmanDirectoryFixture();
     $root = $dir->getPath();
     $watch = $this->watch($root);
     $base = $this->watchmanCommand('find', $root, '.');
     // This is "c:PID:1" because nothing has changed in $root yet
     $clock = $base['clock'];
     // TODO: this should work even if Watchman is suspended. Investigate failure
     // on Travis.
     system("cd {$root}; " . "mkdir d1 d2; " . "touch d1/a; " . "mkdir d3; " . "mv d1 d2 d3; " . "mv d3/* .; " . "mv d1 d2 d3; " . "mv d3/* .; " . "mv d1/a d2; ");
     $this->assertFileListUsingSince($root, $clock, array('d1', 'd2', 'd2/a', 'd3'));
 }
Example #23
0
 function testRemove()
 {
     $dir = new WatchmanDirectoryFixture();
     $root = $dir->getPath();
     mkdir("{$root}/one");
     touch("{$root}/one/onefile");
     mkdir("{$root}/one/two");
     touch("{$root}/one/two/twofile");
     touch("{$root}/top");
     $this->watch($root);
     $this->assertFileList($root, array('one', 'one/onefile', 'one/two', 'one/two/twofile', 'top'));
     $this->watchmanCommand('log', 'debug', 'XXX: remove dir one');
     w_rmdir_recursive("{$root}/one");
     $this->assertFileList($root, array('top'));
     $this->watchmanCommand('log', 'debug', 'XXX: touch file one');
     touch("{$root}/one");
     $this->assertFileList($root, array('one', 'top'));
     $this->watchmanCommand('log', 'debug', 'XXX: unlink file one');
     unlink("{$root}/one");
     $this->assertFileList($root, array('top'));
     if (phutil_is_windows()) {
         // This looks so fugly
         system("rd /s /q {$root}");
         for ($i = 0; $i < 10; $i++) {
             if (!is_dir($root)) {
                 break;
             }
             usleep(20000);
         }
         for ($i = 0; $i < 10; $i++) {
             if (@mkdir("{$root}")) {
                 break;
             }
             usleep(20000);
         }
         @mkdir("{$root}/notme");
     } else {
         system("rm -rf {$root} ; mkdir -p {$root}/notme");
     }
     if (PHP_OS == 'Linux' && getenv('TRAVIS')) {
         $this->assertSkipped('openvz and inotify unlinks == bad time');
     }
     $watches = $this->waitForWatchman(array('watch-list'), function ($list) use($root) {
         return !in_array($root, $list['roots']);
     });
     $this->assertEqual(false, in_array($root, $watches['roots']), "watch deleted");
 }
Example #24
0
 public function callMethod($method, array $params)
 {
     $meta = array();
     if ($this->sessionKey) {
         $meta['sessionKey'] = $this->sessionKey;
     }
     if ($this->connectionID) {
         $meta['connectionID'] = $this->connectionID;
     }
     if ($method == 'conduit.connect') {
         $certificate = idx($params, 'certificate');
         if ($certificate) {
             $token = time();
             $params['authToken'] = $token;
             $params['authSignature'] = sha1($token . $certificate);
         }
         unset($params['certificate']);
     }
     if ($meta) {
         $params['__conduit__'] = $meta;
     }
     $port = null;
     if ($this->port) {
         $port = ':' . $this->port;
     }
     $uri = $this->protocol . '://' . $this->host . $port . '/' . $this->path . $method;
     $data = array('params' => json_encode($params), 'output' => 'json', '__conduit__' => true);
     // NOTE: If we're on Windows, the socket-based HTTPFuture won't work
     // properly. In theory it may be fixable, but the easier fix is just to use
     // the cURL-based HTTPSFuture for HTTP. We'll lose the ability to
     // parallelize requests but things will work correctly.
     $use_https_future = $this->protocol == 'https' || phutil_is_windows();
     if ($use_https_future) {
         $core_future = new HTTPSFuture($uri, $data);
     } else {
         $core_future = new HTTPFuture($uri, $data);
     }
     $core_future->setMethod('POST');
     $core_future->setTimeout($this->timeout);
     $profiler = PhutilServiceProfiler::getInstance();
     $this->profilerCallID = $profiler->beginServiceCall(array('type' => 'conduit', 'method' => $method, 'size' => strlen(http_build_query($data, '', '&'))));
     $conduit_future = new ConduitFuture($core_future);
     $conduit_future->setClient($this, $method);
     $conduit_future->isReady();
     return $conduit_future;
 }
 private function invokeEditor($editor, $path, $offset)
 {
     // NOTE: Popular Windows editors like Notepad++ and GitPad do not support
     // line offsets, so just ignore the offset feature on Windows. We rarely
     // use it anyway.
     $offset_flag = '';
     if ($offset && !phutil_is_windows()) {
         $offset = (int) $offset;
         if (preg_match('/^mate/', $editor)) {
             $offset_flag = csprintf('-l %d', $offset);
         } else {
             $offset_flag = csprintf('+%d', $offset);
         }
     }
     $cmd = csprintf('%C %C %s', $editor, $offset_flag, $path);
     return phutil_passthru('%C', $cmd);
 }
Example #26
0
 function testFishy()
 {
     if (phutil_is_windows()) {
         $this->assertSkipped("simple ln -s without admin on windows");
     }
     $dir = new WatchmanDirectoryFixture();
     $root = $dir->getPath();
     mkdir("{$root}/foo");
     touch("{$root}/foo/a");
     $watch = $this->watch($root);
     $base = $this->watchmanCommand('find', $root, '.');
     // This is "c:PID:1" because nothing has changed in $root yet
     $clock = $base['clock'];
     $this->suspendWatchman();
     system("cd {$root}; " . "mv foo bar; " . "ln -s bar foo");
     $this->resumeWatchman();
     $this->assertFileListUsingSince($root, $clock, array('bar', 'bar/a', 'foo'));
 }
Example #27
0
 function xtestAppendTrigger()
 {
     if (phutil_is_windows()) {
         $this->assertSkipped('no O_APPEND on windows');
     }
     $dir = new WatchmanDirectoryFixture();
     $log = $dir->getPath("log");
     $root = $dir->getPath("dir");
     mkdir($root);
     $this->watch($root);
     $this->trigger($root, array('name' => 'cat', 'command' => $this->catCommand(), 'expression' => array('suffix', 'txt'), 'stdin' => 'NAME_PER_LINE', 'stdout' => ">>{$log}"));
     touch("{$root}/A.txt");
     $this->assertFileContents($log, "A.txt\n");
     touch("{$root}/B.txt");
     $lines = $this->waitForFileToHaveNLines($log, 2);
     sort($lines);
     $this->assertEqual(array("A.txt", "B.txt"), $lines);
 }
 private function formatTestDuration($seconds)
 {
     // Very carefully define inclusive upper bounds on acceptable unit test
     // durations. Times are in milliseconds and are in increasing order.
     $star = "★";
     if (phutil_is_windows()) {
         // Fall-back to normal asterisk for Windows consoles.
         $star = '*';
     }
     $acceptableness = array(50 => "<fg:green>%s</fg><fg:yellow>{$star}</fg> ", 200 => '<fg:green>%s</fg>  ', 500 => '<fg:yellow>%s</fg>  ', INF => '<fg:red>%s</fg>  ');
     $milliseconds = $seconds * 1000;
     $duration = $this->formatTime($seconds);
     foreach ($acceptableness as $upper_bound => $formatting) {
         if ($milliseconds <= $upper_bound) {
             return phutil_console_format($formatting, $duration);
         }
     }
     return phutil_console_format(end($acceptableness), $duration);
 }
Example #29
0
 /**
  * Determines what executables and lint paths to use. Between platforms
  * this also changes whether the lint engine is run under .NET or Mono. It
  * also ensures that all of the required binaries are available for the lint
  * to run successfully.
  *
  * @return void
  */
 private function loadEnvironment()
 {
     if ($this->loaded) {
         return;
     }
     // Determine runtime engine (.NET or Mono).
     if (phutil_is_windows()) {
         $this->runtimeEngine = '';
     } else {
         if (Filesystem::binaryExists('mono')) {
             $this->runtimeEngine = 'mono ';
         } else {
             throw new Exception(pht('Unable to find Mono and you are not on Windows!'));
         }
     }
     // Determine cslint path.
     $cslint = $this->cslintHintPath;
     if ($cslint !== null && file_exists($cslint)) {
         $this->cslintEngine = Filesystem::resolvePath($cslint);
     } else {
         if (Filesystem::binaryExists('cslint.exe')) {
             $this->cslintEngine = 'cslint.exe';
         } else {
             throw new Exception(pht('Unable to locate %s.', 'cslint'));
         }
     }
     // Determine cslint version.
     $ver_future = new ExecFuture('%C -v', $this->runtimeEngine . $this->cslintEngine);
     list($err, $stdout, $stderr) = $ver_future->resolve();
     if ($err !== 0) {
         throw new Exception(pht('You are running an old version of %s. Please ' . 'upgrade to version %s.', 'cslint', self::SUPPORTED_VERSION));
     }
     $ver = (int) $stdout;
     if ($ver < self::SUPPORTED_VERSION) {
         throw new Exception(pht('You are running an old version of %s. Please ' . 'upgrade to version %s.', 'cslint', self::SUPPORTED_VERSION));
     } else {
         if ($ver > self::SUPPORTED_VERSION) {
             throw new Exception(pht('Arcanist does not support this version of %s (it is newer). ' . 'You can try upgrading Arcanist with `%s`.', 'cslint', 'arc upgrade'));
         }
     }
     $this->loaded = true;
 }
 public static function getDisableANSI()
 {
     if (self::$disableANSI === null) {
         $term = phutil_utf8_strtolower(getenv('TERM'));
         // ansicon enables ANSI support on Windows
         if (!$term && getenv('ANSICON')) {
             $term = 'ansi';
         }
         if (phutil_is_windows() && $term !== 'cygwin' && $term !== 'ansi') {
             self::$disableANSI = true;
         } else {
             if (function_exists('posix_isatty') && !posix_isatty(STDOUT)) {
                 self::$disableANSI = true;
             } else {
                 self::$disableANSI = false;
             }
         }
     }
     return self::$disableANSI;
 }