1
0
Fork 0
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:
Aviv Eyal 2023-08-11 09:05:29 -07:00
commit b5140eed54
12 changed files with 125 additions and 22 deletions

1
.gitignore vendored
View file

@ -11,6 +11,7 @@
# User extensions
/externals/includes/*
/src/extensions/*
/resources/ssl/custom.pem
# XHPAST
/support/xhpast/*.a

View file

@ -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

View file

@ -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;
}

View file

@ -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>');
}

View file

@ -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'));
}
}

View file

@ -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']);

View file

@ -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) {

View file

@ -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);
}
}

View file

@ -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;
}

View file

@ -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);
}
}
}

View file

@ -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",

View file

@ -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);