123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351 |
- <?php
- namespace Elgg;
- use UnexpectedValueException;
- /**
- * Provides a structured format for parsing and examining our commit messages.
- *
- * @package Elgg.Core
- * @since 1.9
- *
- * @access private
- */
- class CommitMessage {
- /**
- * Valid parts of the message
- * The index is the index of the $matches array for regex
- * @var array
- */
- private $validMsgParts = array(
- 1 => 'type',
- 2 => 'component',
- 3 => 'summary',
- 5 => 'body'
- );
- /**
- * Message type
- *
- * @var string
- */
- private $type;
- /**
- * Message component
- *
- * @var string
- */
- private $component;
- /**
- * Message summary
- *
- * @var string
- */
- private $summary;
- /**
- * Optional message body
- *
- * @var string
- */
- private $body;
- /**
- * Original message text
- *
- * @var string
- */
- private $originalMsg = '';
- /**
- * Modified message text.
- *
- * @var string
- */
- private $msg = '';
- /**
- * An array of lines over the valid length
- *
- * @var array
- */
- private $lengthyLines;
- /**
- * Valid types
- *
- * @var array
- */
- private static $validTypes = array(
- 'feature',
- 'fix',
- 'docs',
- 'chore',
- 'perf',
- 'security',
- 'deprecate',
- );
- /**
- * Valid components
- *
- * @todo Not checked yet.
- *
- * @var array
- */
- private $validComponents = array(
- 'i18n',
- 'seo',
- 'a11y',
- 'cache',
- 'db',
- 'views',
- 'session',
- 'router'
- );
- /**
- * Ignore messages that match this regex
- *
- * @var string
- */
- private $ignoreRegex = '/^Merge |^Revert /i';
- /**
- * Regex to extract the message parts
- *
- * type(component): message
- * with an optional body following
- *
- * $matches = array(
- * 0 => everything
- * 1 => type
- * 2 => component
- * 3 => summary
- * 4 => body (with leading \ns)
- * 5 => body (without leading \ns)
- * )
- *
- * @var string
- */
- private $formatRegex = "/^(\w*)\(([\w]+)\)\: ([^\n]*)(\n\n?(.*))?$/is";
- /**
- * Max length of any line
- * @var int
- */
- private $maxLineLength = 160;
- /**
- * Checks if a commit message is in the correct format
- *
- * @param string|null $msg The commit message
- */
- public function __construct($msg = null) {
- if ($msg) {
- $this->setMsg($msg);
- }
- }
- /**
- * Sets the active message
- *
- * @param string $msg The message content
- *
- * @return void
- */
- public function setMsg($msg) {
- $this->originalMsg = $msg;
- $msg = str_replace(array("\r", "\n"), "\n", $msg);
- $this->msg = $this->removeComments($msg);
- $this->processMsg();
- }
- /**
- * Return the processed message.
- *
- * @return string
- */
- public function getMsg() {
- return $this->msg;
- }
- /**
- * Return the original message
- *
- * @return string
- */
- public function getOriginalMsg() {
- return $this->originalMsg;
- }
- /**
- * Should this msg be ignored for formatting?
- *
- * @return boolean
- */
- public function shouldIgnore() {
- return preg_match($this->ignoreRegex, $this->msg) === 1;
- }
- /**
- * Process the msg into its parts
- *
- * @return array
- */
- private function processMsg() {
- $matches = array();
-
- preg_match($this->formatRegex, $this->msg, $matches);
- foreach ($this->validMsgParts as $i => $part) {
- $this->$part = isset($matches[$i]) ? $matches[$i] : '';
- }
- $this->lengthyLines = $this->findLengthyLines($this->msg, $this->maxLineLength);
- }
- /**
- * Are all parts of the message valid
- *
- * @return bool
- */
- public function isValid() {
- return $this->isValidFormat() &&
- $this->isValidLineLength() &&
- $this->isValidType();
- }
-
- /**
- * Whether the message format conforms to our standards.
- *
- * @return boolean
- */
- public function isValidFormat() {
- return preg_match($this->formatRegex, $this->msg) === 1;
- }
- /**
- * Are any of the lines too long?
- *
- * @see getLengthyLines() to get line numbers
- *
- * @return bool
- */
- public function isValidLineLength() {
- return count($this->lengthyLines) === 0;
- }
- /**
- * Get the line number of lines that are too long
- *
- * @return array
- */
- public function getLengthyLines() {
- return $this->lengthyLines;
- }
- /**
- * Is the type valid
- *
- * @return boolean
- */
- public function isValidType() {
- return in_array($this->type, self::$validTypes);
- }
- /**
- * Return all valid types
- *
- * @return array
- */
- public static function getValidTypes() {
- return self::$validTypes;
- }
- /**
- * Return the max line length
- *
- * @return int
- */
- public function getMaxLineLength() {
- return $this->maxLineLength;
- }
- /**
- * Sets the max line length allowed.
- * Defaults to 160.
- *
- * @param int $len The maximum length.
- *
- * @return void
- */
- public function setMaxLineLength($len) {
- $this->maxLineLength = (int)$len;
- }
- /**
- * Get part of the message
- *
- * @param string $part One section of the message.
- *
- * @return string
- * @throws UnexpectedValueException
- */
- public function getPart($part) {
- if ($part && in_array($part, $this->validMsgParts)) {
- return $this->$part;
- }
- throw new UnexpectedValueException("`$part` not a valid message part.");
- }
- /**
- * Removes all lines that start with #
- *
- * @param string $msg The msg body of the commit
- *
- * @return string
- */
- public static function removeComments($msg) {
- $msg_arr = array();
- foreach (explode("\n", rtrim($msg)) as $line) {
- if (substr($line, 0, 1) !== '#') {
- $msg_arr[] = $line;
- }
- }
- return implode("\n", $msg_arr);
- }
- /**
- * Returns an array of line numbers > $max_len
- *
- * @param string $msg The content to parse
- * @param int $max_len Maximum length between \n in the $msg
- *
- * @return array
- */
- public static function findLengthyLines($msg, $max_len) {
- $lines = explode("\n", $msg);
- $lengthy_lines = array();
- foreach ($lines as $i => $line) {
- if (strlen($line) > $max_len) {
- $lengthy_lines[] = ++$i;
- }
- }
- return $lengthy_lines;
- }
- /** @inheritDoc */
- public function __toString() {
- return $this->getMsg();
- }
- }
|