mirror of
https://we.phorge.it/source/arcanist.git
synced 2024-11-26 00:32:41 +01:00
Promote 2023.32 to Stable
This commit is contained in:
commit
b5140eed54
12 changed files with 125 additions and 22 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -11,6 +11,7 @@
|
|||
# User extensions
|
||||
/externals/includes/*
|
||||
/src/extensions/*
|
||||
/resources/ssl/custom.pem
|
||||
|
||||
# XHPAST
|
||||
/support/xhpast/*.a
|
||||
|
|
|
@ -34,11 +34,11 @@ If "custom.pem" is present, that file will be used instead of "default.pem".
|
|||
If you receive errors using your "custom.pem" file, you can test it directly
|
||||
with `curl` by running a command like this:
|
||||
|
||||
curl -v --cacert path/to/your/custom.pem https://phabricator.example.com/
|
||||
curl -v --cacert arcanist/resources/ssl/custom.pem https://phorge.example.com/
|
||||
|
||||
Replace "path/to/your/custom.pem" with the path to your "custom.pem" file,
|
||||
and replace "https://phabricator.example.com" with the real URL of your
|
||||
Phabricator install.
|
||||
Replace "arcanist/resources/ssl/custom.pem" with the path to your "custom.pem"
|
||||
file, and replace "https://phorge.example.com" with the real URL of your Phorge
|
||||
install.
|
||||
|
||||
The initial lines of output from `curl` should give you information about the
|
||||
SSL handshake and certificate verification, which may be helpful in resolving
|
||||
|
|
|
@ -15,7 +15,7 @@ final class ArcanistBrowseObjectNameURIHardpointQuery
|
|||
$token_set = array();
|
||||
foreach ($refs as $key => $ref) {
|
||||
$token = $ref->getToken();
|
||||
if (!strlen($token)) {
|
||||
if (!phutil_nonempty_string($token)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -41,7 +41,7 @@ final class ArcanistBrowseObjectNameURIHardpointQuery
|
|||
continue;
|
||||
}
|
||||
|
||||
$uri = idx($object, 'uri');
|
||||
$uri = idx($object, 'uri', '');
|
||||
if (!strlen($uri)) {
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -142,7 +142,7 @@ EOTEXT
|
|||
if ($many_hits) {
|
||||
foreach ($many_hits as $ref) {
|
||||
$token = $ref->getToken();
|
||||
if (strlen($token)) {
|
||||
if (phutil_nonempty_string($token)) {
|
||||
$message = pht('Argument "%s" is ambiguous.', $token);
|
||||
} else {
|
||||
$message = pht('Default behavior is ambiguous.');
|
||||
|
@ -167,7 +167,7 @@ EOTEXT
|
|||
|
||||
foreach ($many_hits as $ref) {
|
||||
$token_display = $ref->getToken();
|
||||
if (!strlen($token)) {
|
||||
if (!phutil_nonempty_string($token)) {
|
||||
$token_display = pht('<default>');
|
||||
}
|
||||
|
||||
|
|
|
@ -561,4 +561,32 @@ final class PhutilURI extends Phobject {
|
|||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* This is just a complicated type-check - we'll eventually replace it with a
|
||||
* native type-hint of `PhutilURI | string | null`, when this type-hint is
|
||||
* available (php 8.0).
|
||||
*
|
||||
* Before php 8, and after we suspect there aren't many more cases where this
|
||||
* fails, we'll replace the log with an exception.
|
||||
*/
|
||||
public static function checkHrefType($value) {
|
||||
if ($value === null || is_string($value)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($value instanceof PhutilURI) {
|
||||
return;
|
||||
}
|
||||
|
||||
$report_type = is_object($value) ? get_class($value) : gettype($value);
|
||||
|
||||
// We log stuff with a kind stack trace
|
||||
phlog(
|
||||
pht(
|
||||
'Unexpected value type provided for an HREF field - %s. '.
|
||||
'Please share this stack trace as comment in Task %s',
|
||||
$report_type,
|
||||
'https://we.phorge.it/T15316'));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -66,7 +66,7 @@ final class ArcanistRepositoryRef
|
|||
));
|
||||
|
||||
foreach ($params as $key => $value) {
|
||||
if (!strlen($value)) {
|
||||
if ($value === null || !strlen($value)) {
|
||||
unset($params[$key]);
|
||||
}
|
||||
}
|
||||
|
@ -79,7 +79,7 @@ final class ArcanistRepositoryRef
|
|||
|
||||
$params = $params + $defaults;
|
||||
|
||||
$uri_base = $this->browseURI;
|
||||
$uri_base = coalesce($this->browseURI, '');
|
||||
$uri_base = rtrim($uri_base, '/');
|
||||
|
||||
$uri_branch = phutil_escape_uri_path_component($params['branch']);
|
||||
|
|
|
@ -92,7 +92,7 @@ EOTEXT
|
|||
$argv = $this->getArgument('argv');
|
||||
|
||||
$is_generate = $this->getArgument('generate');
|
||||
$is_shell = (bool)strlen($this->getArgument('shell'));
|
||||
$is_shell = phutil_nonempty_string($this->getArgument('shell'));
|
||||
$is_current = $this->getArgument('current');
|
||||
|
||||
if ($argv) {
|
||||
|
|
|
@ -40,4 +40,17 @@ final class ArcanistUnitTestResultTestCase extends PhutilTestCase {
|
|||
}
|
||||
}
|
||||
|
||||
public function testRenderer() {
|
||||
$result = new ArcanistUnitTestResult();
|
||||
$result->setName('RendererTest');
|
||||
$result->setResult('pass');
|
||||
$result->setDuration(0.001);
|
||||
$result->setUserData('');
|
||||
|
||||
$renderer = new ArcanistUnitConsoleRenderer();
|
||||
$output = $renderer->renderUnitResult($result);
|
||||
$test_dscr = 'Renderer copes with null namespace';
|
||||
$this->assertTrue((bool)preg_match('/PASS/', $output), $test_dscr);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ final class ArcanistUnitConsoleRenderer extends ArcanistUnitRenderer {
|
|||
|
||||
$test_name = $result->getName();
|
||||
$test_namespace = $result->getNamespace();
|
||||
if (strlen($test_namespace)) {
|
||||
if (phutil_nonempty_string($test_namespace)) {
|
||||
$test_name = $test_namespace.'::'.$test_name;
|
||||
}
|
||||
|
||||
|
|
|
@ -1004,11 +1004,18 @@ final class PhutilUtilsTestCase extends PhutilTestCase {
|
|||
|
||||
$uri = new PhutilURI('http://example.org/');
|
||||
|
||||
// Each test is defined in this way:
|
||||
// 0: subject $value
|
||||
// 1: expected result from phutil_nonempty_string($value)
|
||||
// 2: expected result from phutil_nonempty_stringlike($value)
|
||||
// 3: expected result from phutil_nonempty_scalar($value)
|
||||
// 4: human test name
|
||||
$map = array(
|
||||
array(null, false, false, false, 'literal null'),
|
||||
array('', false, false, false, 'empty string'),
|
||||
array('x', true, true, true, 'nonempty string'),
|
||||
array(false, null, null, null, 'bool'),
|
||||
array(false, null, null, false, 'false bool'),
|
||||
array(true, null, null, true, 'true bool'),
|
||||
array(1, null, null, true, 'integer'),
|
||||
array($uri, null, true, true, 'uri object'),
|
||||
array(2.5, null, null, true, 'float'),
|
||||
|
@ -1070,4 +1077,50 @@ final class PhutilUtilsTestCase extends PhutilTestCase {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
public function testStringCasting() {
|
||||
$cases = array(
|
||||
array(123, '123', 'number'),
|
||||
array(null, '', 'null to empty string'),
|
||||
array('text', 'text', 'string'),
|
||||
array(17.4, '17.4', 'float'),
|
||||
array(true, '1', 'boolean true (well done php?)'),
|
||||
array(false, '', 'boolean false (to empty string)'),
|
||||
array(0, '0', 'zero (int)'),
|
||||
array(0.0, '0', 'zero (float'),
|
||||
array(
|
||||
new PhutilURI('http://www.example.com'),
|
||||
'http://www.example.com',
|
||||
'Object with toString()',
|
||||
),
|
||||
);
|
||||
|
||||
$exception_cases = array(
|
||||
array(array(), 'array'),
|
||||
);
|
||||
|
||||
foreach ($cases as $test_case) {
|
||||
list($input, $expected_output, $test_name) = $test_case;
|
||||
|
||||
$actual = phutil_string_cast($input);
|
||||
|
||||
$this->assertEqual($expected_output, $actual, $test_name);
|
||||
}
|
||||
|
||||
|
||||
$expect_exceptions = array('Exception');
|
||||
foreach ($exception_cases as $test_case) {
|
||||
list($input, $test_name) = $test_case;
|
||||
|
||||
try {
|
||||
phutil_string_cast($input);
|
||||
} catch (Exception $ex) {
|
||||
$caught = $ex;
|
||||
} catch (Throwable $ex) {
|
||||
$caught = $ex;
|
||||
}
|
||||
|
||||
$this->assertCaught($expect_exceptions, $caught, $test_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -718,13 +718,10 @@ function phutil_utf8_convert($string, $to_encoding, $from_encoding) {
|
|||
'mbstring'));
|
||||
}
|
||||
|
||||
$result = @mb_convert_encoding($string, $to_encoding, $from_encoding);
|
||||
|
||||
if ($result === false) {
|
||||
$message = error_get_last();
|
||||
if ($message) {
|
||||
$message = idx($message, 'message', pht('Unknown error.'));
|
||||
}
|
||||
try {
|
||||
$result = mb_convert_encoding($string, $to_encoding, $from_encoding);
|
||||
} catch (Throwable $ex) {
|
||||
$message = $ex->getMessage();
|
||||
throw new Exception(
|
||||
pht(
|
||||
"String conversion from encoding '%s' to encoding '%s' failed: %s",
|
||||
|
|
|
@ -900,7 +900,7 @@ function array_mergev(array $arrayv) {
|
|||
* NOTE: This function does not treat "\r" on its own as a newline because none
|
||||
* of SVN, Git or Mercurial do on any OS.
|
||||
*
|
||||
* @param string Block of text to be split into lines.
|
||||
* @param string|PhutilSafeHTML $corpus Block of text to be split into lines.
|
||||
* @param bool If true, retain line endings in result strings.
|
||||
* @return list List of lines.
|
||||
*
|
||||
|
@ -908,7 +908,7 @@ function array_mergev(array $arrayv) {
|
|||
* @phutil-external-symbol function phutil_safe_html
|
||||
*/
|
||||
function phutil_split_lines($corpus, $retain_endings = true) {
|
||||
if (!strlen($corpus)) {
|
||||
if (!phutil_nonempty_stringlike($corpus)) {
|
||||
return array('');
|
||||
}
|
||||
|
||||
|
@ -2187,6 +2187,9 @@ function phutil_nonempty_stringlike($value) {
|
|||
* string other than the empty string, integers, and floats are considered
|
||||
* scalar.
|
||||
*
|
||||
* Note that booleans are also valid scalars, where false is considered empty,
|
||||
* and true is non-empty since if you cast true to string, it's non-empty.
|
||||
*
|
||||
* This method raises an exception if passed any other value.
|
||||
*
|
||||
* @param Value to test.
|
||||
|
@ -2205,6 +2208,14 @@ function phutil_nonempty_scalar($value) {
|
|||
return true;
|
||||
}
|
||||
|
||||
// Booleans are also valid scalars by PHP. Inventing the opposite can be
|
||||
// too much esoteric and problematic.
|
||||
// false: empty, because casted to string becomes '' (empty)
|
||||
// true: non-empty, because casted to string becomes '1' (non-empty)
|
||||
if ($value === false || $value === true) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
if (is_object($value)) {
|
||||
try {
|
||||
$string = phutil_string_cast($value);
|
||||
|
|
Loading…
Reference in a new issue