1 | <?php |
||
2 | |||
3 | namespace App\Main\Plugin; |
||
4 | |||
5 | use SavinMikhail\CommentsDensity\AnalyzeComments\Analyzer\DTO\Output\CommentDTO; |
||
6 | use SavinMikhail\CommentsDensity\AnalyzeComments\Analyzer\DTO\Output\Report; |
||
7 | use SavinMikhail\CommentsDensity\AnalyzeComments\Comments\FixMeComment; |
||
8 | use SavinMikhail\CommentsDensity\AnalyzeComments\Comments\TodoComment; |
||
9 | use SavinMikhail\CommentsDensity\AnalyzeComments\Config\DTO\Config; |
||
10 | use SavinMikhail\CommentsDensity\AnalyzeComments\File\FileEditor; |
||
11 | use SavinMikhail\CommentsDensity\Plugin\PluginInterface; |
||
12 | use Symfony\Component\HttpClient\HttpClient; |
||
13 | use Symfony\Contracts\HttpClient\HttpClientInterface; |
||
14 | |||
15 | final readonly class OpenIssue implements PluginInterface |
||
0 ignored issues
–
show
Bug
introduced
by
![]() |
|||
16 | { |
||
17 | private const YOUTRACK_URL = 'https://yt'; |
||
18 | private const AUTHORIZATION_TOKEN = ''; |
||
19 | private const PROJECT_ID = '59-178'; |
||
20 | private const STAGE = 'Второй этап'; |
||
21 | private const BRANCH_NAME = 'develop'; |
||
22 | private const GITLAB_PROJECT_URL = 'https://gitlab/backend'; |
||
23 | |||
24 | public function handle(Report $report, Config $config): void |
||
25 | { |
||
26 | $httpClient = HttpClient::create(); |
||
27 | foreach ($report->comments as $comment) { |
||
28 | if (!in_array($comment->commentType, [TodoComment::NAME, FixMeComment::NAME], true)) { |
||
29 | continue; |
||
30 | } |
||
31 | |||
32 | if ($this->hasIssueUrl($comment->content)) { |
||
33 | continue; |
||
34 | } |
||
35 | |||
36 | $draftId = $this->createDraft($httpClient, $comment); |
||
37 | $issueId = $this->createIssueFromDraft($httpClient, $draftId); |
||
38 | $issueUrl = self::YOUTRACK_URL . '/issue/' . $issueId; |
||
39 | $newComment = new CommentDTO( |
||
40 | commentType: $comment->commentType, |
||
41 | commentTypeColor: $comment->commentTypeColor, |
||
42 | file: $comment->file, |
||
43 | line: $comment->line, |
||
44 | content: rtrim($comment->content) . " ($issueUrl)", |
||
45 | ); |
||
46 | (new FileEditor())->updateCommentInFile($newComment); |
||
47 | } |
||
48 | } |
||
49 | |||
50 | private function buildDescription(CommentDTO $comment): string |
||
51 | { |
||
52 | $gitlabUrl = self::GITLAB_PROJECT_URL . '/-/blob/' . self::BRANCH_NAME . $comment->file . '?ref_type=heads#L' . $comment->line; |
||
53 | return |
||
54 | "**Comment**: $comment->content \n" |
||
55 | . "**File**: $comment->file \n" |
||
56 | . "**Line**: $comment->line \n" |
||
57 | . "**Gitlab url**: $gitlabUrl \n"; |
||
58 | } |
||
59 | |||
60 | private function buildSummary(): string |
||
61 | { |
||
62 | return 'Сфера > ' . self::STAGE . ' > Back > Техдолг'; |
||
63 | } |
||
64 | |||
65 | private function createDraft(HttpClientInterface $httpClient, CommentDTO $comment): string |
||
66 | { |
||
67 | $response = $httpClient->request( |
||
68 | 'POST', |
||
69 | self::YOUTRACK_URL . '/api/users/me/drafts?$top=-1&fields=$type,applicableActions(description,executing,id,name,userInputType),attachments($type,author(fullName,id,ringId),comment(id,visibility($type)),created,id,imageDimensions(height,width),issue(id,project(id,ringId),visibility($type)),mimeType,name,removed,size,thumbnailURL,url,visibility($type,implicitPermittedUsers($type,avatarUrl,banBadge,banned,email,fullName,id,isLocked,issueRelatedGroup(icon),login,name,online,profiles(general(trackOnlineStatus)),ringId),permittedGroups($type,allUsersGroup,icon,id,name,ringId),permittedUsers($type,avatarUrl,banBadge,banned,email,fullName,id,isLocked,issueRelatedGroup(icon),login,name,online,profiles(general(trackOnlineStatus)),ringId))),canAddPublicComment,canUpdateVisibility,comments(attachments($type,author(fullName,id,ringId),comment(id,visibility($type)),created,id,imageDimensions(height,width),issue(id,project(id,ringId),visibility($type)),mimeType,name,removed,size,thumbnailURL,url,visibility($type,implicitPermittedUsers($type,avatarUrl,banBadge,banned,email,fullName,id,isLocked,issueRelatedGroup(icon),login,name,online,profiles(general(trackOnlineStatus)),ringId),permittedGroups($type,allUsersGroup,icon,id,name,ringId),permittedUsers($type,avatarUrl,banBadge,banned,email,fullName,id,isLocked,issueRelatedGroup(icon),login,name,online,profiles(general(trackOnlineStatus)),ringId))),id),created,description,externalIssue(key,name,url),fields($type,hasStateMachine,id,isUpdatable,name,projectCustomField($type,bundle(id),canBeEmpty,emptyFieldText,field(fieldType(isMultiValue,valueType),id,localizedName,name,ordinal),id,isEstimation,isPublic,isSpentTime,ordinal,size),value($type,archived,avatarUrl,buildIntegration,buildLink,color(background,id),description,fullName,id,isResolved,localizedName,login,markdownText,minutes,name,presentation,ringId,text)),hasEmail,hiddenAttachmentsCount,id,idReadable,isDraft,links(direction,id,issuesSize,linkType(aggregation,directed,localizedName,localizedSourceToTarget,localizedTargetToSource,name,sourceToTarget,targetToSource,uid),trimmedIssues($type,comments($type),created,id,idReadable,isDraft,numberInProject,project(id,ringId),reporter(id),resolved,summary,voters(hasVote),votes,watchers(hasStar)),unresolvedIssuesSize),mentionedArticles(idReadable,summary),mentionedIssues(idReadable,resolved,summary),mentionedUsers($type,avatarUrl,banBadge,banned,canReadProfile,fullName,id,isLocked,login,name,ringId),messages,numberInProject,project($type,id,isDemo,leader(id),name,plugins(helpDeskSettings(enabled),timeTrackingSettings(enabled,estimate(field(id,name),id),timeSpent(field(id,name),id)),vcsIntegrationSettings(processors(enabled,migrationFailed,server(enabled,url),upsourceHubResourceKey,url))),ringId,shortName,team($type,allUsersGroup,icon,id,name,ringId)),reporter($type,avatarUrl,banBadge,banned,email,fullName,id,isLocked,issueRelatedGroup(icon),login,name,online,profiles(general(trackOnlineStatus)),ringId),resolved,summary,tags(color(id),id,isUpdatable,isUsable,name,owner(id),query),updated,updater($type,avatarUrl,banBadge,banned,email,fullName,id,isLocked,issueRelatedGroup(icon),login,name,online,profiles(general(trackOnlineStatus)),ringId),usesMarkdown,visibility($type,implicitPermittedUsers($type,avatarUrl,banBadge,banned,email,fullName,id,isLocked,issueRelatedGroup(icon),login,name,online,profiles(general(trackOnlineStatus)),ringId),permittedGroups($type,allUsersGroup,icon,id,name,ringId),permittedUsers($type,avatarUrl,banBadge,banned,email,fullName,id,isLocked,issueRelatedGroup(icon),login,name,online,profiles(general(trackOnlineStatus)),ringId)),voters(hasVote),votes,watchers(hasStar),widgets(base,indexPath,place,pluginName)', |
||
70 | [ |
||
71 | 'headers' => [ |
||
72 | 'Content-Type' => 'application/json', |
||
73 | 'Authorization' => 'Bearer ' . self::AUTHORIZATION_TOKEN, |
||
74 | ], |
||
75 | 'json' => [ |
||
76 | 'summary' => $this->buildSummary(), |
||
77 | 'description' => $this->buildDescription($comment), |
||
78 | 'project' => ['id' => self::PROJECT_ID], |
||
79 | ], |
||
80 | ] |
||
81 | ); |
||
82 | $response = $response->toArray(); |
||
83 | return $response['id']; // looks like 68-107353 |
||
84 | } |
||
85 | |||
86 | private function createIssueFromDraft(HttpClientInterface $httpClient, string $draftId): string |
||
87 | { |
||
88 | $response = $httpClient->request( |
||
89 | 'POST', |
||
90 | self::YOUTRACK_URL . "/api/issues?draftId={$draftId}&\$top=-1&fields=id,idReadable,numberInProject,messages", |
||
91 | [ |
||
92 | 'headers' => [ |
||
93 | 'Content-Type' => 'application/json', |
||
94 | 'Authorization' => 'Bearer ' . self::AUTHORIZATION_TOKEN, |
||
95 | ], |
||
96 | 'json' => [ |
||
97 | 'issueId' => $draftId, |
||
98 | ], |
||
99 | ] |
||
100 | ); |
||
101 | $response = $response->toArray(); |
||
102 | return $response['idReadable']; // looks like mossphere-287 |
||
103 | } |
||
104 | |||
105 | private function hasIssueUrl(string $commentContent): bool |
||
106 | { |
||
107 | return (bool)preg_match('/https:\/\/yt\.kr\.digital\/issue\/\w+-\d+/', $commentContent); |
||
108 | } |
||
109 | } |
||
110 |