diff --git a/README.md b/README.md index 33021be..0054e2e 100644 --- a/README.md +++ b/README.md @@ -72,8 +72,10 @@ go build -o jira-parser cmd/jira-parser/main.go ```yaml jira: base_url: "https://your-domain.atlassian.net" - username: "your-email@example.com" # для Atlassian Cloud используйте email - token: "your-api-token" # API токен для аутентификации + username: "your-email@example.com" # Для Atlassian Cloud используйте email + token: "your-api-token" # API токен для аутентификации (Personal Access Token) + # Для Basic Auth используйте: token: "basic your-password" + # Для Bearer токена используйте: token: "bearer your-token" parsing: version_patterns: @@ -111,8 +113,11 @@ parsing: "not applicable": "N/A" ``` -Для Atlassian Cloud используйте email в качестве username и API токен. -Для self-hosted JIRA можно использовать username и пароль или API токен. +Для аутентификации поддерживаются следующие методы: + +- **Personal Access Token** (рекомендуется для Atlassian Cloud): используйте email в качестве username и API токен в поле token +- **Basic Auth** (для self-hosted JIRA): используйте username и пароль, указав префикс "basic" в поле token +- **Bearer Token** (для некоторых OAuth-конфигураций): используйте префикс "bearer" в поле token Также создайте файл `configs/tickets.yaml` для указания тикетов, которые нужно обработать: @@ -127,7 +132,7 @@ tickets: ### Поддерживаемые методы аутентификации - **Personal Access Token**: `token: "your-api-token"` -- **Basic Auth**: `token: "your-password"` +- **Basic Auth**: `token: "basic your-password"` - **Bearer Token**: `token: "bearer your-token"` ## Безопасность @@ -173,12 +178,18 @@ tickets: # Получить QA комментарии с фильтрацией по результату ./jira-parser parse TOS-30690 --result="Fixed" +# или с короткой формой +./jira-parser parse TOS-30690 -r "Fixed" # Получить QA комментарии с фильтрацией по дате создания ./jira-parser parse TOS-30690 --date-from=2023-01-01 --date-to=2023-12-31 +# или с короткими формами +./jira-parser parse TOS-30690 -d 2023-01-01 -t 2023-12-31 # Получить QA комментарии с фильтрацией по нескольким критериям ./jira-parser parse TOS-30690 --result="Fixed" --date-from=2023-01-01 +# или с короткими формами +./jira-parser parse TOS-30690 -r "Fixed" -d 2023-01-01 ``` ### Получение последнего QA комментария @@ -192,6 +203,8 @@ tickets: # Получить последние QA комментарии для тикетов из указанного YAML-файла ./jira-parser last-comment --tickets-file ./my-tickets.yaml +# или с короткой формой +./jira-parser last-comment -f ./my-tickets.yaml ``` ### Получение версии приложения @@ -212,12 +225,18 @@ tickets: # Обработать тикеты из указанного YAML-файла ./jira-parser parse-multiple --tickets-file ./my-tickets.yaml +# или с короткой формой +./jira-parser parse-multiple -f ./my-tickets.yaml # Обработать тикеты с фильтрацией по результату ./jira-parser parse-multiple TOS-30690 TOS-30692 --result="Fixed" +# или с короткой формой +./jira-parser parse-multiple TOS-30690 TOS-30692 -r "Fixed" # Обработать тикеты с фильтрацией по дате создания ./jira-parser parse-multiple TOS-30690 TOS-30692 --date-from=2023-01-01 --date-to=2023-12-31 +# или с короткими формами +./jira-parser parse-multiple TOS-30690 TOS-30692 -d 2023-01-01 -t 2023-12-31 ``` ### Экспорт данных в JSON и HTML @@ -228,15 +247,21 @@ tickets: # Экспорт с форматированием ./jira-parser export TOS-30690 --pretty +# или с короткой формой +./jira-parser export TOS-30690 -p # Экспорт в HTML ./jira-parser export TOS-30690 --format html --output-dir ./reports +# или с короткими формами +./jira-parser export TOS-30690 -F html -o ./reports # Экспорт нескольких тикетов ./jira-parser export TOS-30690 TOS-30692 # Экспорт тикетов из файла ./jira-parser export --tickets-file ./my-tickets.yaml +# или с короткой формой +./jira-parser export -f ./my-tickets.yaml ``` ## Пример вывода diff --git a/internal/infrastructure/jira/client.go b/internal/infrastructure/jira/client.go index d5252c1..bc4ac80 100644 --- a/internal/infrastructure/jira/client.go +++ b/internal/infrastructure/jira/client.go @@ -12,6 +12,11 @@ import ( "github.com/rd2w/jira-parser/internal/infrastructure/auth" ) +const ( + // QAOwnerField represents the custom field for QA Owner in JIRA + QAOwnerField = "customfield_12601" +) + type JiraClient struct { client *jira.Client parsingConfig domain.ParsingConfig @@ -70,9 +75,13 @@ func (jc *JiraClient) GetIssueInfo(issueKey string) (*domain.IssueInfo, error) { assigneeEmail = issue.Fields.Assignee.EmailAddress } - // В JIRA нет специального поля "QA Owner", но мы можем определить QA владельца как - // пользователя, оставившего последний QA комментарий - qaOwnerEmail := jc.getQaOwnerEmail(issue) + // Попробуем получить QA владельца из кастомного поля customfield_12601 + qaOwnerEmail := jc.getQaOwnerFromCustomField(issue) + + // Если кастомное поле пустое, используем резервную логику - последний QA комментарий + if qaOwnerEmail == "" { + qaOwnerEmail = jc.getQaOwnerFromLastComment(issue) + } return &domain.IssueInfo{ Key: issue.Key, @@ -367,8 +376,21 @@ func (jc *JiraClient) removeJiraFormatting(text string) string { return strings.TrimSpace(text) } -// getQaOwnerEmail определяет QA владельца как пользователя, оставившего последний QA комментарий -func (jc *JiraClient) getQaOwnerEmail(issue *jira.Issue) string { +// getQaOwnerFromCustomField пытается получить email QA владельца из кастомного поля +func (jc *JiraClient) getQaOwnerFromCustomField(issue *jira.Issue) string { + if qaOwnerField, exists := issue.Fields.Unknowns[QAOwnerField]; exists && qaOwnerField != nil { + // Проверяем, что поле содержит структуру пользователя с email + if userMap, ok := qaOwnerField.(map[string]interface{}); ok { + if email, ok := userMap["emailAddress"].(string); ok && email != "" { + return email + } + } + } + return "" +} + +// getQaOwnerFromLastComment определяет QA владельца как пользователя, оставившего последний QA комментарий +func (jc *JiraClient) getQaOwnerFromLastComment(issue *jira.Issue) string { if issue.Fields.Comments == nil { return "" } diff --git a/internal/interfaces/cli/docs.go b/internal/interfaces/cli/docs.go index a28b7f3..db8393d 100644 --- a/internal/interfaces/cli/docs.go +++ b/internal/interfaces/cli/docs.go @@ -43,7 +43,7 @@ Supports multiple output formats: markdown, man, rest, and yaml.`, } cmd.Flags().StringVarP(&outputDir, "output", "o", "./docs", "Output directory for documentation") - cmd.Flags().StringVarP(&format, "format", "f", "markdown", "Output format (markdown, offline-help)") + cmd.Flags().StringVarP(&format, "format", "F", "markdown", "Output format (markdown, offline-help)") return cmd } @@ -59,9 +59,9 @@ Parse all QA comments for an issue Usage: jira-parser parse Flags: - --result string Filter comments by test result (e.g., Fixed, Not Fixed, etc.) - --date-from string Filter comments created after specified date (format: YYYY-MM-DD) - --date-to string Filter comments created before specified date (format: YYYY-MM-DD) + -r, --result string Filter comments by test result (e.g., Fixed, Not Fixed, etc.) + -d, --date-from string Filter comments created after specified date (format: YYYY-MM-DD) + -t, --date-to string Filter comments created before specified date (format: YYYY-MM-DD) ### last-comment Get the last QA comment for an issue @@ -69,7 +69,7 @@ Get the last QA comment for an issue Usage: jira-parser last-comment [issue-key...] Flags: - --tickets-file Path to the YAML file containing the list of tickets (default: ./configs/tickets.yaml) + -f, --tickets-file Path to the YAML file containing the list of tickets (default: ./configs/tickets.yaml) ### export Export all QA comments as JSON or HTML @@ -78,9 +78,9 @@ Usage: jira-parser export [issue-key...] Flags: -p, --pretty Pretty print JSON output - -f, --format Output format (json or html) (default "json") - --output-dir Output directory for exported files (default "./QA_comments") - --tickets-file Path to the YAML file containing the list of tickets (default: ./configs/tickets.yaml) + -F, --format Output format (json or html) (default "json") + -o, --output-dir Output directory for exported files (default "./QA_comments") + -f, --tickets-file Path to the YAML file containing the list of tickets (default: ./configs/tickets.yaml) ### parse-multiple Parse QA comments for multiple tickets from tickets file or command line arguments @@ -88,10 +88,10 @@ Parse QA comments for multiple tickets from tickets file or command line argumen Usage: jira-parser parse-multiple [tickets...] Flags: - --result string Filter comments by test result (e.g., Fixed, Not Fixed, etc.) - --date-from string Filter comments created after specified date (format: YYYY-MM-DD) - --date-to string Filter comments created before specified date (format: YYYY-MM-DD) - --tickets-file Path to the YAML file containing the list of tickets (default: ./configs/tickets.yaml) + -r, --result string Filter comments by test result (e.g., Fixed, Not Fixed, etc.) + -d, --date-from string Filter comments created after specified date (format: YYYY-MM-DD) + -t, --date-to string Filter comments created before specified date (format: YYYY-MM-DD) + -f, --tickets-file Path to the YAML file containing the list of tickets (default: ./configs/tickets.yaml) ### version Print the version number of jira-parser @@ -104,7 +104,7 @@ Generate CLI documentation Usage: jira-parser docs Flags: - -f, --format string Output format (markdown, offline-help) (default "markdown") + -F, --format string Output format (markdown, offline-help) (default "markdown") -o, --output string Output directory for documentation (default "./docs") ### tutorial @@ -181,9 +181,9 @@ COMMAND SPECIFICS: parse command: Usage: jira-parser parse Flags: - --result string Filter comments by test result (e.g., Fixed, Not Fixed, etc.) - --date-from string Filter comments created after specified date (format: YYYY-MM-DD) - --date-to string Filter comments created before specified date (format: YYYY-MM-DD) + -r, --result string Filter comments by test result (e.g., Fixed, Not Fixed, etc.) + -d, --date-from string Filter comments created after specified date (format: YYYY-MM-DD) + -t, --date-to string Filter comments created before specified date (format: YYYY-MM-DD) last-comment command: Usage: jira-parser last-comment @@ -192,27 +192,27 @@ export command: Usage: jira-parser export [issue-key...] Flags: --pretty, -p Pretty print JSON output - --format, -f Output format (json or html) (default: "json") - --output-dir Output directory for exported files (default: "./QA_comments") - --tickets-file Path to the YAML file containing the list of tickets (default: ./configs/tickets.yaml) + --format, -F Output format (json or html) (default: "json") + --output-dir, -o Output directory for exported files (default: "./QA_comments") + --tickets-file, -f Path to the YAML file containing the list of tickets (default: ./configs/tickets.yaml) last-comment command: Usage: jira-parser last-comment [issue-key...] Flags: - --tickets-file Path to the YAML file containing the list of tickets (default: ./configs/tickets.yaml) + -f, --tickets-file Path to the YAML file containing the list of tickets (default: ./configs/tickets.yaml) parse-multiple command: Usage: jira-parser parse-multiple [tickets...] Flags: - --result string Filter comments by test result (e.g., Fixed, Not Fixed, etc.) - --date-from string Filter comments created after specified date (format: YYYY-MM-DD) - --date-to string Filter comments created before specified date (format: YYYY-MM-DD) - --tickets-file Path to the YAML file containing the list of tickets (default: ./configs/tickets.yaml) + -r, --result string Filter comments by test result (e.g., Fixed, Not Fixed, etc.) + -d, --date-from string Filter comments created after specified date (format: YYYY-MM-DD) + -t, --date-to string Filter comments created before specified date (format: YYYY-MM-DD) + -f, --tickets-file Path to the YAML file containing the list of tickets (default: ./configs/tickets.yaml) docs command: Usage: jira-parser docs Flags: - --format value, -f value Output format (markdown, offline-help) (default: "markdown") + --format value, -F value Output format (markdown, offline-help) (default: "markdown") --output value, -o value Output directory for documentation (default: "./docs") tutorial command: diff --git a/internal/interfaces/cli/export.go b/internal/interfaces/cli/export.go index 2c6c008..96ae3bd 100644 --- a/internal/interfaces/cli/export.go +++ b/internal/interfaces/cli/export.go @@ -103,9 +103,9 @@ Example: jira-parser export --tickets-file ./my-tickets.yaml --format html --out } cmd.Flags().BoolP("pretty", "p", false, "Pretty print JSON output") - cmd.Flags().StringVar(&ticketsFile, "tickets-file", "", "Path to the YAML file containing the list of tickets (default: ./configs/tickets.yaml)") - cmd.Flags().StringVarP(&outputFormat, "format", "f", "json", "Output format: json or html") - cmd.Flags().StringVar(&outputDir, "output-dir", "", "Output directory for exported files (default: ./QA_comments)") + cmd.Flags().StringVarP(&ticketsFile, "tickets-file", "f", "", "Path to the YAML file containing the list of tickets (default: ./configs/tickets.yaml)") + cmd.Flags().StringVarP(&outputFormat, "format", "F", "json", "Output format: json or html") + cmd.Flags().StringVarP(&outputDir, "output-dir", "o", "", "Output directory for exported files (default: ./QA_comments)") return cmd } diff --git a/internal/interfaces/cli/last_comment.go b/internal/interfaces/cli/last_comment.go index 21d43c8..f3d107c 100644 --- a/internal/interfaces/cli/last_comment.go +++ b/internal/interfaces/cli/last_comment.go @@ -66,7 +66,7 @@ Example: jira-parser last-comment --tickets-file ./my-tickets.yaml`, }, } - cmd.Flags().StringVar(&ticketsFile, "tickets-file", "", "Path to the YAML file containing the list of tickets (default: ./configs/tickets.yaml)") + cmd.Flags().StringVarP(&ticketsFile, "tickets-file", "f", "", "Path to the YAML file containing the list of tickets (default: ./configs/tickets.yaml)") return cmd } diff --git a/internal/interfaces/cli/parse.go b/internal/interfaces/cli/parse.go index fd687d0..931bba9 100644 --- a/internal/interfaces/cli/parse.go +++ b/internal/interfaces/cli/parse.go @@ -99,9 +99,9 @@ func NewParseCommand() *cobra.Command { }, } - cmd.Flags().StringVar(&resultFilter, "result", "", "Filter comments by test result (e.g., Fixed, Not Fixed, etc.)") - cmd.Flags().StringVar(&dateFrom, "date-from", "", "Filter comments created after specified date (format: YYYY-MM-DD)") - cmd.Flags().StringVar(&dateTo, "date-to", "", "Filter comments created before specified date (format: YYYY-MM-DD)") + cmd.Flags().StringVarP(&resultFilter, "result", "r", "", "Filter comments by test result (e.g., Fixed, Not Fixed, etc.)") + cmd.Flags().StringVarP(&dateFrom, "date-from", "d", "", "Filter comments created after specified date (format: YYYY-MM-DD)") + cmd.Flags().StringVarP(&dateTo, "date-to", "t", "", "Filter comments created before specified date (format: YYYY-MM-DD)") return cmd } diff --git a/internal/interfaces/cli/root.go b/internal/interfaces/cli/root.go index 91a418d..eae4012 100644 --- a/internal/interfaces/cli/root.go +++ b/internal/interfaces/cli/root.go @@ -178,10 +178,10 @@ Example: jira-parser parse-multiple --tickets-file ./my-tickets.yaml`, }, } - cmd.Flags().StringVar(&resultFilter, "result", "", "Filter comments by test result (e.g., Fixed, Not Fixed, etc.)") - cmd.Flags().StringVar(&dateFrom, "date-from", "", "Filter comments created after specified date (format: YYYY-MM-DD)") - cmd.Flags().StringVar(&dateTo, "date-to", "", "Filter comments created before specified date (format: YYYY-MM-DD)") - cmd.Flags().StringVar(&ticketsFile, "tickets-file", "", "Path to the YAML file containing the list of tickets (default: ./configs/tickets.yaml)") + cmd.Flags().StringVarP(&resultFilter, "result", "r", "", "Filter comments by test result (e.g., Fixed, Not Fixed, etc.)") + cmd.Flags().StringVarP(&dateFrom, "date-from", "d", "", "Filter comments created after specified date (format: YYYY-MM-DD)") + cmd.Flags().StringVarP(&dateTo, "date-to", "t", "", "Filter comments created before specified date (format: YYYY-MM-DD)") + cmd.Flags().StringVarP(&ticketsFile, "tickets-file", "f", "", "Path to the YAML file containing the list of tickets (default: ./configs/tickets.yaml)") return cmd }