/** * @param CommitMessage $commitMessage * @return ChangeInfoEnvelope */ public function parse(CommitMessage $commitMessage) { $fullBody = $commitMessage->getBody(); $splittedBodies = explode("\n\n", $fullBody); $lastBody = $splittedBodies[count($splittedBodies) - 1]; $changeInfoList = []; $version = null; $environment = null; if (self::containsVersion($lastBody)) { $version = self::extractTag(ChangeInfoEnvelope::VP_VERSION_TAG, $lastBody); $environment = self::extractTag(ChangeInfoEnvelope::VP_ENVIRONMENT_TAG, $lastBody); array_pop($splittedBodies); } if (!self::isTrackedChangeInfo($fullBody)) { return new ChangeInfoEnvelope([new UntrackedChangeInfo($commitMessage)], $version, $environment); } foreach ($splittedBodies as $body) { $partialCommitMessage = new CommitMessage("", $body); $actionTag = $partialCommitMessage->getVersionPressTag(TrackedChangeInfo::ACTION_TAG); list($scope, $action, $id) = array_pad(explode('/', $actionTag, 3), 3, null); $tags = $partialCommitMessage->getVersionPressTags(); unset($tags[TrackedChangeInfo::ACTION_TAG]); $actionsInfo = $this->actionsInfoProvider->getActionsInfo($scope); if ($this->dbSchema->isEntity($scope)) { $entityInfo = $this->dbSchema->getEntityInfo($scope); $changeInfoList[] = new EntityChangeInfo($entityInfo, $actionsInfo, $action, $id, $tags, []); } else { $changeInfoList[] = new TrackedChangeInfo($scope, $actionsInfo, $action, $id, $tags, []); } } return new ChangeInfoEnvelope($changeInfoList, $version, $environment); }
/** * Returns matching ChangeInfo type for a given commit message. Matching is done based on the value of the VP-Action tag. * * @param CommitMessage $commitMessage * @throws Exception When no matching ChangeInfo type is found (should never happen) * @return string "Class" of the matching ChangeInfo object */ public static function findMatchingChangeInfo(CommitMessage $commitMessage) { if (substr_count($commitMessage->getBody(), TrackedChangeInfo::ACTION_TAG) > 1) { return "VersionPress\\ChangeInfos\\ChangeInfoEnvelope"; } $actionTagValue = $commitMessage->getVersionPressTag(TrackedChangeInfo::ACTION_TAG); // can be empty string which is not a problem foreach (self::$changeInfoMap as $actionTagExpression => $changeInfoType) { $regex = "~^" . $actionTagExpression . "\$~"; if (preg_match($regex, $actionTagValue)) { return $changeInfoType; } } // Code execution should never reach this point, at least the 'UntrackedChangeInfo' should match throw new Exception("Matching ChangeInfo type not found"); }
/** * Factory method - builds a ChangeInfo object from a commit message. Used when VersionPress * table is constructed; hooks use the normal constructor. * * @param CommitMessage $commitMessage * @return ChangeInfo */ public static function buildFromCommitMessage(CommitMessage $commitMessage) { $fullBody = $commitMessage->getBody(); $splittedBodies = explode("\n\n", $fullBody); $lastBody = $splittedBodies[count($splittedBodies) - 1]; $changeInfoList = array(); $version = null; if (self::containsVersion($lastBody)) { $version = self::extractVersion($lastBody); array_pop($splittedBodies); } foreach ($splittedBodies as $body) { $partialCommitMessage = new CommitMessage("", $body); /** @var ChangeInfo $matchingChangeInfoType */ $matchingChangeInfoType = ChangeInfoMatcher::findMatchingChangeInfo($partialCommitMessage); $changeInfoList[] = $matchingChangeInfoType::buildFromCommitMessage($partialCommitMessage); } return new self($changeInfoList, $version); }