Issues (52)

docs/examples/OpenIssue.php (1 issue)

Labels
Severity
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
A parse error occurred: Syntax error, unexpected T_READONLY, expecting T_CLASS on line 15 at column 6
Loading history...
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