1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-10 08:52:39 +01:00

Fix an issue in Owners where a transaction change could show too many effects

Summary:
Fixes T13324. Ref PHI1288. Currently, if you edit an Owners package that has some paths with no trailing slashes (like `README.md`) so their internal names and display names differ (`/README.md` display, vs `/README.md/` internal), the "Show Details" in the transaction log shows the path as re-normalized even if you didn't touch it.

Instead, be more careful about handling display paths vs internal paths.

(This code on the whole is significantly less clear than it probably could be, but this issue is so minor that I'm hesitant to start ripping things out.)

Test Plan:
  - In a package with some paths like `/src/` and some paths like `/src`:
  - Added new paths.
  - Removed paths.
  - Changed paths from `/src/` to `/src`.
  - Changed paths from `/src` to `/src/`.

In all cases, the "paths" list and the transaction record identically reflected the edit in the way I expected them to.

Reviewers: amckinley

Reviewed By: amckinley

Maniphest Tasks: T13324

Differential Revision: https://secure.phabricator.com/D20596
This commit is contained in:
epriestley 2019-06-20 11:10:52 -07:00
parent 37e26f1b45
commit 53f8ad14fa
2 changed files with 46 additions and 6 deletions

View file

@ -79,15 +79,27 @@ final class PhabricatorOwnersPath extends PhabricatorOwnersDAO {
public static function getSetFromTransactionValue(array $v) {
$set = array();
foreach ($v as $ref) {
$set[$ref['repositoryPHID']][$ref['path']][$ref['excluded']] = true;
$key = self::getScalarKeyForRef($ref);
$set[$key] = true;
}
return $set;
}
public static function isRefInSet(array $ref, array $set) {
return isset($set[$ref['repositoryPHID']][$ref['path']][$ref['excluded']]);
$key = self::getScalarKeyForRef($ref);
return isset($set[$key]);
}
private static function getScalarKeyForRef(array $ref) {
return sprintf(
'repository=%s path=%s display=%s excluded=%d',
$ref['repositoryPHID'],
$ref['path'],
$ref['display'],
$ref['excluded']);
}
/**
* Get the number of directory matches between this path specification and
* some real path.

View file

@ -12,12 +12,33 @@ final class PhabricatorOwnersPackagePathsTransaction
public function generateNewValue($object, $value) {
$new = $value;
foreach ($new as $key => $info) {
$new[$key]['excluded'] = (int)idx($info, 'excluded');
$info['excluded'] = (int)idx($info, 'excluded');
// The input has one "path" key with the display path.
// Move it to "display", then normalize the value in "path".
$display_path = $info['path'];
$raw_path = rtrim($display_path, '/').'/';
$info['path'] = $raw_path;
$info['display'] = $display_path;
$new[$key] = $info;
}
return $new;
}
public function getTransactionHasEffect($object, $old, $new) {
list($add, $rem) = PhabricatorOwnersPath::getTransactionValueChanges(
$old,
$new);
return ($add || $rem);
}
public function validateTransactions($object, array $xactions) {
$errors = array();
@ -110,8 +131,8 @@ final class PhabricatorOwnersPackagePathsTransaction
$display_map = array();
$seen_map = array();
foreach ($new as $key => $spec) {
$display_path = $spec['path'];
$raw_path = rtrim($display_path, '/').'/';
$raw_path = $spec['path'];
$display_path = $spec['display'];
// If the user entered two paths in the same repository which normalize
// to the same value (like "src/main.c" and "src/main.c/"), discard the
@ -193,11 +214,18 @@ final class PhabricatorOwnersPackagePathsTransaction
$rowc = array();
foreach ($rows as $key => $row) {
$rowc[] = $row['class'];
if (array_key_exists('display', $row)) {
$display_path = $row['display'];
} else {
$display_path = $row['path'];
}
$rows[$key] = array(
$row['change'],
$row['excluded'] ? pht('Exclude') : pht('Include'),
$this->renderHandle($row['repositoryPHID']),
$row['path'],
$display_path,
);
}