diff --git a/src/PHPCensor/Languages/lang.en.php b/src/PHPCensor/Languages/lang.en.php index a8b17bb6..dac686f5 100644 --- a/src/PHPCensor/Languages/lang.en.php +++ b/src/PHPCensor/Languages/lang.en.php @@ -180,9 +180,10 @@ PHP Censor', 'group_save' => 'Save Group', // View Build - 'errors' => 'Errors', - 'information' => 'Information', - + 'errors' => 'Errors', + 'information' => 'Information', + 'is_new' => 'Is new?', + 'new' => 'New', 'build_x_not_found' => 'Build with ID %d does not exist.', 'build_n' => 'Build %d', 'rebuild_now' => 'Rebuild Now', @@ -328,7 +329,7 @@ PHP Censor', 'build-summary' => 'Summary', 'stage' => 'Stage', 'duration' => 'Duration', - 'seconds' => 'sec.', + 'seconds' => 'sec.', 'plugin' => 'Plugin', 'stage_setup' => 'Setup', 'stage_test' => 'Test', @@ -344,7 +345,7 @@ PHP Censor', 'all_severities' => 'All severities', 'filters' => 'Filters', 'errors_selected' => 'Errors selected', - + 'build_details' => 'Build Details', 'commit_details' => 'Commit Details', 'committer' => 'Committer', @@ -419,7 +420,7 @@ PHP Censor', 'confirm_cancel' => 'Cancel', 'confirm_success' => 'Item successfully deleted.', 'confirm_failed' => 'Deletion failed! Server says: ', - + 'public_status_title' => 'Public status', 'public_status_image' => 'Status image', 'public_status_page' => 'Public status page', diff --git a/src/PHPCensor/Languages/lang.ru.php b/src/PHPCensor/Languages/lang.ru.php index a4f680a2..22ca05a8 100644 --- a/src/PHPCensor/Languages/lang.ru.php +++ b/src/PHPCensor/Languages/lang.ru.php @@ -175,6 +175,8 @@ PHP Censor', // View Build 'errors' => 'Ошибки', 'information' => 'Информация', + 'new' => 'Новая', + 'is_new' => 'Новая?', 'build_x_not_found' => 'Сборки с ID %d не существует.', 'build_n' => 'Сборка %d', 'rebuild_now' => 'Пересобрать сейчас', @@ -352,7 +354,7 @@ PHP Censor', 'passing_build' => 'Успех сборки', 'failing_build' => 'Провал сборки', 'log_output' => 'Вывод лога: ', - + // Error Levels: 'critical' => 'Критичный', 'high' => 'Высокий', diff --git a/src/PHPCensor/Migrations/20171209135004_added_new_label_for_errors.php b/src/PHPCensor/Migrations/20171209135004_added_new_label_for_errors.php new file mode 100644 index 00000000..4716f028 --- /dev/null +++ b/src/PHPCensor/Migrations/20171209135004_added_new_label_for_errors.php @@ -0,0 +1,44 @@ +hasTable('build_error')) { + $table = $this->table('build_error'); + + if (!$table->hasColumn('hash')) { + $table + ->addColumn('hash', 'string', ['limit' => 32, 'default' => '']) + ->save(); + } + + if (!$table->hasColumn('is_new')) { + $table + ->addColumn('is_new', 'boolean', ['default' => false]) + ->save(); + } + } + } + + public function down() + { + if ($this->hasTable('build_error')) { + $table = $this->table('build_error'); + + if ($table->hasColumn('hash')) { + $table + ->removeColumn('hash') + ->save(); + } + + if ($table->hasColumn('is_new')) { + $table + ->removeColumn('is_new') + ->save(); + } + } + } +} diff --git a/src/PHPCensor/Model/BuildError.php b/src/PHPCensor/Model/BuildError.php index 3e8796dc..bfb0bc20 100644 --- a/src/PHPCensor/Model/BuildError.php +++ b/src/PHPCensor/Model/BuildError.php @@ -40,6 +40,8 @@ class BuildError extends Model 'severity' => null, 'message' => null, 'create_date' => null, + 'hash' => null, + 'is_new' => null, ]; /** @@ -56,6 +58,8 @@ class BuildError extends Model 'severity' => 'getSeverity', 'message' => 'getMessage', 'create_date' => 'getCreateDate', + 'hash' => 'getHash', + 'is_new' => 'getIsNew', // Foreign key getters: 'Build' => 'getBuild', @@ -75,6 +79,8 @@ class BuildError extends Model 'severity' => 'setSeverity', 'message' => 'setMessage', 'create_date' => 'setCreateDate', + 'hash' => 'setHash', + 'is_new' => 'setIsNew', // Foreign key setters: 'Build' => 'setBuild', @@ -174,6 +180,26 @@ class BuildError extends Model return $rtn; } + /** + * @return string + */ + public function getHash() + { + $rtn = (string)$this->data['hash']; + + return $rtn; + } + + /** + * @return string + */ + public function getIsNew() + { + $rtn = $this->data['is_new']; + + return $rtn; + } + /** * @param $value int */ @@ -324,6 +350,40 @@ class BuildError extends Model $this->setModified('create_date'); } + /** + * @param $value string + */ + public function setHash($value) + { + $this->validateNotNull('hash', $value); + $this->validateString('hash', $value); + + if ($this->data['hash'] === $value) { + return; + } + + $this->data['hash'] = $value; + + $this->setModified('hash'); + } + + /** + * @param $value int + */ + public function setIsNew($value) + { + $this->validateNotNull('is_new', $value); + $this->validateInt('is_new', $value); + + if ($this->data['is_new'] === $value) { + return; + } + + $this->data['is_new'] = $value; + + $this->setModified('is_new'); + } + /** * Get the Build model for this BuildError by Id. * @@ -425,6 +485,21 @@ class BuildError extends Model } } + /** + * @param string $plugin + * @param string $file + * @param integer $lineStart + * @param integer $lineEnd + * @param integer $severity + * @param string $message + * + * @return string + */ + public static function generateHash($plugin, $file, $lineStart, $lineEnd, $severity, $message) + { + return md5($plugin . $file . $lineStart . $lineEnd . $severity . $message); + } + /** * Get the class to apply to HTML elements representing this error. * diff --git a/src/PHPCensor/Plugin/TechnicalDebt.php b/src/PHPCensor/Plugin/TechnicalDebt.php index f966c7f6..e9998bc3 100644 --- a/src/PHPCensor/Plugin/TechnicalDebt.php +++ b/src/PHPCensor/Plugin/TechnicalDebt.php @@ -53,7 +53,7 @@ class TechnicalDebt extends Plugin implements ZeroConfigPluginInterface { return 'technical_debt'; } - + /** * {@inheritdoc} */ diff --git a/src/PHPCensor/Store/BuildErrorStore.php b/src/PHPCensor/Store/BuildErrorStore.php index 05bcc6eb..7ccedb7d 100644 --- a/src/PHPCensor/Store/BuildErrorStore.php +++ b/src/PHPCensor/Store/BuildErrorStore.php @@ -201,7 +201,7 @@ class BuildErrorStore extends Store */ public function getKnownSeverities($buildId, $plugin = '') { - $query = 'SELECT DISTINCT {{severity}} from {{build_error}} WHERE {{build_id}} = :build'; + $query = 'SELECT DISTINCT {{severity}} FROM {{build_error}} WHERE {{build_id}} = :build'; if ($plugin) { $query .= ' AND {{plugin}} = :plugin'; } @@ -225,4 +225,28 @@ class BuildErrorStore extends Store return []; } } + + /** + * Check if a build error is new. + * + * @param string $hash + * + * @return boolean + */ + public function getIsNewError($hash) + { + $query = 'SELECT COUNT(*) AS {{total}} FROM {{build_error}} WHERE {{hash}} = :hash'; + + $stmt = Database::getConnection('read')->prepareCommon($query); + + $stmt->bindValue(':hash', $hash); + + if ($stmt->execute()) { + $res = $stmt->fetch(\PDO::FETCH_ASSOC); + + return (0 === $res['total']); + } + + return true; + } } diff --git a/src/PHPCensor/Store/BuildErrorWriter.php b/src/PHPCensor/Store/BuildErrorWriter.php index 4e71b3c5..4ad68097 100644 --- a/src/PHPCensor/Store/BuildErrorWriter.php +++ b/src/PHPCensor/Store/BuildErrorWriter.php @@ -4,6 +4,8 @@ namespace PHPCensor\Store; use b8\Config; use b8\Database; +use PHPCensor\Model\BuildError; +use b8\Store\Factory; /** * Class BuildErrorWriter @@ -69,6 +71,11 @@ class BuildErrorWriter if (is_null($createdDate)) { $createdDate = new \DateTime(); } + + /** @var BuildErrorStore $errorStore */ + $errorStore = Factory::getStore('BuildError'); + $hash = BuildError::generateHash($plugin, $file, $lineStart, $lineEnd, $severity, $message); + $this->errors[] = [ 'plugin' => (string)$plugin, 'message' => (string)$message, @@ -77,6 +84,8 @@ class BuildErrorWriter 'line_start' => !is_null($lineStart) ? (int)$lineStart : null, 'line_end' => !is_null($lineEnd) ? (int)$lineEnd : null, 'create_date' => $createdDate->format('Y-m-d H:i:s'), + 'hash' => $hash, + 'is_new' => (integer)$errorStore->getIsNewError($hash), ]; if (count($this->errors) >= $this->bufferSize) { @@ -104,7 +113,9 @@ class BuildErrorWriter :line_end' . $i . ', :severity' . $i . ', :message' . $i . ', - :create_date' . $i . ' + :create_date' . $i . ', + :hash' . $i . ', + :is_new' . $i . ' )'; $insertValuesData['build_id' . $i] = $this->buildId; $insertValuesData['plugin' . $i] = $error['plugin']; @@ -114,6 +125,8 @@ class BuildErrorWriter $insertValuesData['severity' . $i] = $error['severity']; $insertValuesData['message' . $i] = $error['message']; $insertValuesData['create_date' . $i] = $error['create_date']; + $insertValuesData['hash' . $i] = $error['hash']; + $insertValuesData['is_new' . $i] = $error['is_new']; } $query = ' INSERT INTO {{build_error}} ( @@ -124,12 +137,15 @@ class BuildErrorWriter {{line_end}}, {{severity}}, {{message}}, - {{create_date}} + {{create_date}}, + {{hash}}, + {{is_new}} ) VALUES ' . join(', ', $insertValuesPlaceholders) . ' '; $stmt = Database::getConnection('write')->prepareCommon($query); $stmt->execute($insertValuesData); + $this->errors = []; } } diff --git a/src/PHPCensor/View/Build/errors.phtml b/src/PHPCensor/View/Build/errors.phtml index 1db34032..b5c080b3 100644 --- a/src/PHPCensor/View/Build/errors.phtml +++ b/src/PHPCensor/View/Build/errors.phtml @@ -14,19 +14,24 @@ foreach ($errors as $error):