diff --git a/src/applications/differential/parser/DifferentialChangesetParser.php b/src/applications/differential/parser/DifferentialChangesetParser.php --- a/src/applications/differential/parser/DifferentialChangesetParser.php +++ b/src/applications/differential/parser/DifferentialChangesetParser.php @@ -542,6 +542,12 @@ PhutilEventEngine::dispatchEvent($event); $generated = $event->getValue('is_generated'); + + $attribute = $this->changeset->isGeneratedChangeset(); + if ($attribute) { + $generated = true; + } + $this->specialAttributes[self::ATTR_GENERATED] = $generated; } diff --git a/src/applications/differential/storage/DifferentialChangeset.php b/src/applications/differential/storage/DifferentialChangeset.php --- a/src/applications/differential/storage/DifferentialChangeset.php +++ b/src/applications/differential/storage/DifferentialChangeset.php @@ -12,7 +12,7 @@ protected $awayPaths; protected $changeType; protected $fileType; - protected $metadata; + protected $metadata = array(); protected $oldProperties; protected $newProperties; protected $addLines; @@ -24,6 +24,11 @@ const TABLE_CACHE = 'differential_changeset_parse_cache'; + const METADATA_TRUSTED_ATTRIBUTES = 'attributes.trusted'; + const METADATA_UNTRUSTED_ATTRIBUTES = 'attributes.untrusted'; + + const ATTRIBUTE_GENERATED = 'generated'; + protected function getConfiguration() { return array( self::CONFIG_SERIALIZATION => array( @@ -266,6 +271,90 @@ return null; } + public function setChangesetMetadata($key, $value) { + if (!is_array($this->metadata)) { + $this->metadata = array(); + } + + $this->metadata[$key] = $value; + + return $this; + } + + public function getChangesetMetadata($key, $default = null) { + if (!is_array($this->metadata)) { + return $default; + } + + return idx($this->metadata, $key, $default); + } + + private function setInternalChangesetAttribute($trusted, $key, $value) { + if ($trusted) { + $meta_key = self::METADATA_TRUSTED_ATTRIBUTES; + } else { + $meta_key = self::METADATA_UNTRUSTED_ATTRIBUTES; + } + + $attributes = $this->getChangesetMetadata($meta_key, array()); + $attributes[$key] = $value; + $this->setChangesetMetadata($meta_key, $attributes); + + return $this; + } + + private function getInternalChangesetAttributes($trusted) { + if ($trusted) { + $meta_key = self::METADATA_TRUSTED_ATTRIBUTES; + } else { + $meta_key = self::METADATA_UNTRUSTED_ATTRIBUTES; + } + + return $this->getChangesetMetadata($meta_key, array()); + } + + public function setTrustedChangesetAttribute($key, $value) { + return $this->setInternalChangesetAttribute(true, $key, $value); + } + + public function getTrustedChangesetAttributes() { + return $this->getInternalChangesetAttributes(true); + } + + public function getTrustedChangesetAttribute($key, $default = null) { + $map = $this->getTrustedChangesetAttributes(); + return idx($map, $key, $default); + } + + public function setUntrustedChangesetAttribute($key, $value) { + return $this->setInternalChangesetAttribute(false, $key, $value); + } + + public function getUntrustedChangesetAttributes() { + return $this->getInternalChangesetAttributes(false); + } + + public function getUntrustedChangesetAttribute($key, $default = null) { + $map = $this->getUntrustedChangesetAttributes(); + return idx($map, $key, $default); + } + + public function getChangesetAttributes() { + // Prefer trusted values over untrusted values when both exist. + return + $this->getTrustedChangesetAttributes() + + $this->getUntrustedChangesetAttributes(); + } + + public function getChangesetAttribute($key, $default = null) { + $map = $this->getChangesetAttributes(); + return idx($map, $key, $default); + } + + public function isGeneratedChangeset() { + return $this->getChangesetAttribute(self::ATTRIBUTE_GENERATED); + } + /* -( PhabricatorPolicyInterface )----------------------------------------- */ diff --git a/src/applications/differential/storage/DifferentialDiff.php b/src/applications/differential/storage/DifferentialDiff.php --- a/src/applications/differential/storage/DifferentialDiff.php +++ b/src/applications/differential/storage/DifferentialDiff.php @@ -226,6 +226,8 @@ $changeset->setAddLines($add_lines); $changeset->setDelLines($del_lines); + self::detectGeneratedCode($changeset); + $diff->addUnsavedChangeset($changeset); } $diff->setLineCount($lines); @@ -821,5 +823,48 @@ ); } + private static function detectGeneratedCode( + DifferentialChangeset $changeset) { + + $is_generated_trusted = self::isTrustedGeneratedCode($changeset); + + $changeset->setTrustedChangesetAttribute( + DifferentialChangeset::ATTRIBUTE_GENERATED, + $is_generated_trusted); + + $is_generated_untrusted = self::isUntrustedGeneratedCode($changeset); + + $changeset->setUntrustedChangesetAttribute( + DifferentialChangeset::ATTRIBUTE_GENERATED, + $is_generated_untrusted); + } + + private static function isTrustedGeneratedCode( + DifferentialChangeset $changeset) { + + $filename = $changeset->getFilename(); + + $paths = PhabricatorEnv::getEnvConfig('differential.generated-paths'); + foreach ($paths as $regexp) { + if (preg_match($regexp, $filename)) { + return true; + } + } + + return false; + } + + private static function isUntrustedGeneratedCode( + DifferentialChangeset $changeset) { + + if ($changeset->getHunks()) { + $new_data = $changeset->makeNewFile(); + if (strpos($new_data, '@'.'generated') !== false) { + return true; + } + } + + return false; + } }