diff --git a/.gitignore b/.gitignore index e7cc715..a578487 100644 --- a/.gitignore +++ b/.gitignore @@ -15,4 +15,7 @@ # vendor/ #Ignore IntelliJ project folder -.idea \ No newline at end of file +.idea + +#Ignore binary builds +main diff --git a/CHANGELOG.md b/CHANGELOG.md index d6b48ae..fa62f75 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + ## [0.1.0] - tbd + ### Added + - GitLab support + ## [0.1.1] - 2021-02-19 ### Changed - Golang version 1.15 -> 1.16 diff --git a/README.md b/README.md index b183d24..6d15813 100644 --- a/README.md +++ b/README.md @@ -6,52 +6,62 @@ A tool to sent comments to Issues or Pull Requests in Github from CI tools. --- +### Platforms + +| Supported platforms | Fully supported | In development | +|---------------------|-----------------|----------------| +| Github | ✔ | | +| GitLab | ✔ | | +| BitBucket | | ✔ | ### Usage Required environment variables: -* `GITHUB_COMMENT_USER` - User from which name will be sent comments to Github -* `GITHUB_COMMENT_TOKEN` - Personal Token for comment user. [Github doc](https://docs.github.com/en/github/authenticating-to-github/creating-a-personal-access-token) +* `API_USER` - User from which name will be sent comments. +* `API_TOKEN` - Personal Token for comment user. Available parameters: ``` -usage: CommentCI [-h|--help] -o|--github-owner "" -r|--github-repository - "" [-s|--single-comment ""] [-c|--codify] - [-f|--file "" [-f|--file "" ...]] - [-l|--file-comment "" [-l|--file-comment "" - ...]] -i|--issue-number [-m|--multi-comment] +usage: CommentCI [-h|--help] -o|--owner "" -r|--repository "" + [-s|--single-comment ""] [-c|--codify] [-f|--file + "" [-f|--file "" ...]] [-l|--file-comment + "" [-l|--file-comment "" ...]] -i|--issue-number + [-m|--multi-comment] -p|--platform (github|gitlab) + [-g|--target-type (issue|merge-request)] Sent a comment to GitHub PR or Issue from your CI Arguments: - -h --help Print help information - -o --github-owner Owner of the repository. User/Organisations. - -r --github-repository Name of the github repository. - -s --single-comment Single comment string to sent to GitHub. - -c --codify Put comments to the Markdown code block. - -f --file By repeating this flag you can specify multiple - files which content will be sent to comment. - -l --file-comment By repeating this flag you can specify comments for - provided files in according order. - -i --issue-number Number(id) of the Issue/PR to sent a comment. - -m --multi-comment Put each file into a separate comment in GitHub.. - Default: false + -h --help Print help information + -o --owner Owner of the repository. User/Organisations. + -r --repository Name of the repository. + -s --single-comment Single comment string to sent to GitHub. + -c --codify Put format to the Markdown code block. + -f --file By repeating this flag you can specify multiple files + which content will be sent to comment. + -l --file-comment By repeating this flag you can specify format for + provided files in according order. + -i --issue-number Number(id) of the Issue/PR to sent a comment. + -m --multi-comment Put each file into a separate comment in GitHub.. + Default: false + -p --platform Select platform where to send format + -g --target-type Select type of comment target (GitLab only) ``` Usage examples:

Single comment: ``` -GITHUB_COMMENT_USER=user GITHUB_COMMENT_TOKEN=xxx commentci -o repo_owner -r repo_name -i 2 -s "Single comment" +API_USER=user API_TOKEN=xxx commentci -g github -o repo_owner -r repo_name -i 2 -s "Single comment" ```

Single file with a comment: ``` -GITHUB_COMMENT_USER=user GITHUB_COMMENT_TOKEN=xxx commentci -o repo_owner -r repo_name -i 2 -c -l "Comment to example file" -f ./example.txt +API_USER=user API_TOKEN=xxx commentci -g github -o repo_owner -r repo_name -i 2 -c -l "Comment to example file" -f ./example.txt ```

Multiple files with comments: ``` -GITHUB_COMMENT_USER=user GITHUB_COMMENT_TOKEN=xxx commentci -o repo_owner -r repo_name -i 2 -c -l "Comment to example file 1" -f ./example_1.txt -l "Comment to example file 2" -f ./example_2.txt +API_USER=user API_TOKEN=xxx commentci -g github -o repo_owner -r repo_name -i 2 -c -l "Comment to example file 1" -f ./example_1.txt -l "Comment to example file 2" -f ./example_2.txt ``` \ No newline at end of file diff --git a/VERSION b/VERSION index 6da28dd..341cf11 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.1.1 \ No newline at end of file +0.2.0 \ No newline at end of file diff --git a/cmd/main.go b/cmd/main.go index 5d1caee..51a1c4b 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -1,39 +1,41 @@ package main import ( - cmt "github.com/ThelonKarrde/CommentCI/internal/comments" "github.com/ThelonKarrde/CommentCI/internal/config" + "github.com/ThelonKarrde/CommentCI/internal/format" ghi "github.com/ThelonKarrde/CommentCI/internal/github" + glb "github.com/ThelonKarrde/CommentCI/internal/gitlab" "github.com/ThelonKarrde/CommentCI/internal/utils" "log" ) func main() { - data := config.ReadConfig() - if data.CommentText != "" { - if len(data.FileList) != 0 { - log.Println("Warning! Both single-comment and file-comment args are specified! Priority over single comment flag.") - } - comment := cmt.MakeComment(data.CommentText, "", data.CodeStyleMode) - ghi.CommentIssue(&comment, data.GitHubCommentToken, data.GitHubRepoOwner, data.GitHubRepoName, data.IssueNumber) + cfg := config.ReadConfig() + var comments []string + if cfg.CommentText != "" { + comments = append(comments, format.Comment(cfg.CommentText, "", cfg.CodeStyleMode)) } else { - if data.MultiCommentMode == false { - if data.FileList != nil { - comment := cmt.MakeSingleComment(utils.ConvertFilesToStrings(data.FileList), data.CommentFiles, data.CodeStyleMode) - ghi.CommentIssue(&comment, data.GitHubCommentToken, data.GitHubRepoOwner, data.GitHubRepoName, data.IssueNumber) + if cfg.MultiCommentMode { + for i, p := range cfg.FileList { + cmt := "" + if i < len(cfg.CommentFiles) { + cmt = cfg.CommentFiles[i] + } + comments = append(comments, format.Comment(utils.ReadFileToString(p), cmt, cfg.CodeStyleMode)) + } + } else { + if len(cfg.FileList) > 0 { + comments = append(comments, format.SingleComment(utils.ConvertFilesToStrings(cfg.FileList), cfg.CommentFiles, cfg.CodeStyleMode)) } else { log.Fatalf("No files specified!") } + } + } + for _, c := range comments { + if cfg.Platform == "github" { + ghi.Comment(&c, cfg.ApiToken, cfg.RepoOwner, cfg.RepoName, cfg.IssueNumber) } else { - for i, p := range data.FileList { - var comment string - if i >= len(data.CommentFiles) { - comment = cmt.MakeComment(utils.ReadFileToString(p), "", data.CodeStyleMode) - } else { - comment = cmt.MakeComment(utils.ReadFileToString(p), data.CommentFiles[i], data.CodeStyleMode) - } - ghi.CommentIssue(&comment, data.GitHubCommentToken, data.GitHubRepoOwner, data.GitHubRepoName, data.IssueNumber) - } + glb.Comment(cfg.TargetType, &c, cfg.ApiToken, cfg.RepoOwner, cfg.RepoName, cfg.IssueNumber) } } } diff --git a/go.mod b/go.mod index c56b5a9..dbc574a 100644 --- a/go.mod +++ b/go.mod @@ -5,6 +5,6 @@ go 1.16 require ( github.com/akamensky/argparse v1.2.2 github.com/google/go-github v17.0.0+incompatible - github.com/google/go-querystring v1.0.0 // indirect + github.com/xanzy/go-gitlab v0.44.0 golang.org/x/oauth2 v0.0.0-20210201163806-010130855d6c ) diff --git a/go.sum b/go.sum index 3b94fc2..ae8c0c3 100644 --- a/go.sum +++ b/go.sum @@ -42,6 +42,7 @@ github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMn github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= @@ -99,6 +100,11 @@ github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hf github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= +github.com/hashicorp/go-cleanhttp v0.5.1 h1:dH3aiDG9Jvb5r5+bYHsikaOUIpcM0xvgMXVoDkXMzJM= +github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= +github.com/hashicorp/go-retryablehttp v0.6.4 h1:BbgctKO892xEyOXnGiaAwIoSq1QZ/SS4AhjoAh9DnfY= +github.com/hashicorp/go-retryablehttp v0.6.4/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= @@ -112,7 +118,11 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/xanzy/go-gitlab v0.44.0 h1:cEiGhqu7EpFGuei2a2etAwB+x6403E5CvpLn35y+GPs= +github.com/xanzy/go-gitlab v0.44.0/go.mod h1:sPLojNBn68fMUWSxIJtdVVIP8uSBYqesTfDUseX11Ug= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -158,6 +168,7 @@ golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181108082009-03003ca0c849/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -184,6 +195,7 @@ golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81R golang.org/x/net v0.0.0-20200822124328-c89045814202 h1:VvcQYSHwXgi7W+TpUR6A9g6Up98WAHf3f/ulnJ62IyA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20181106182150-f42d05182288/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -230,6 +242,7 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20191024005414-555d28b269f0 h1:/5xXl8Y5W96D+TtHSlonuFqGHIWVuyCkGJLwGh9JJFs= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -292,6 +305,7 @@ google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0M google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= diff --git a/internal/comments/comments.go b/internal/comments/comments.go deleted file mode 100644 index 6671122..0000000 --- a/internal/comments/comments.go +++ /dev/null @@ -1,34 +0,0 @@ -package comments - -func CodifyText(text string) string { - return "```\n" + text + "\n```\n" -} - -func AppendComment(text string, comment string) string { - return comment + "\n" + text + "\n" -} - -func MakeComment(text string, comment string, codify bool) string { - if codify == true { - return AppendComment(CodifyText(text), comment) - } - return AppendComment(text, comment) -} - -func MakeSingleComment(rawText []string, rawComment []string, codify bool) string { - if len(rawText) == 1 { - if len(rawComment) > 0 { - return MakeComment(rawText[0], rawComment[0], codify) - } - return MakeComment(rawText[0], "", codify) - } - var result string - for i, t := range rawText { - if i >= len(rawComment) { - result += MakeComment(t, "", codify) - } else { - result += MakeComment(t, rawComment[i], codify) - } - } - return result -} diff --git a/internal/config/config.go b/internal/config/config.go index a133d11..9a567a1 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -7,79 +7,99 @@ import ( ) type Data struct { - GitHubRepoOwner string - GitHubRepoName string - GitHubCommentUser string - GitHubCommentToken string - CommentText string - CommentFiles []string - FileList []string - CodeStyleMode bool - IssueNumber int - MultiCommentMode bool + RepoOwner string + RepoName string + ApiUser string + ApiToken string + Platform string + TargetType string + CommentText string + CommentFiles []string + FileList []string + CodeStyleMode bool + IssueNumber int + MultiCommentMode bool } func readEnvConfig(data *Data) *Data { - ghcu, ok := os.LookupEnv("GITHUB_COMMENT_USER") + apiUser, ok := os.LookupEnv("API_USER") if !ok { - log.Fatalf("No GitHub user specified! Check GITHUB_COMMENT_USER env.") + apiUser, ok = os.LookupEnv("GITHUB_COMMENT_USER") + if !ok { + log.Println("Warning! No API user specified! Check API_USER env.") + } + log.Println("GITHUB_COMMENT_USER environment variable deprecated, use API_USER instead!") } - data.GitHubCommentUser = ghcu - ghct, ok := os.LookupEnv("GITHUB_COMMENT_TOKEN") + data.ApiUser = apiUser + apiToken, ok := os.LookupEnv("API_TOKEN") if !ok { - log.Fatalf("No GitHub token specified! Check GITHUB_COMMENT_TOKEN env.") + apiToken, ok = os.LookupEnv("GITHUB_COMMENT_TOKEN") + if !ok { + log.Fatalf("No API token specified! Check API_TOKEN env.") + } + log.Println("GITHUB_COMMENT_TOKEN environment variable deprecated, use API_TOKEN instead!") } - data.GitHubCommentToken = ghct + data.ApiToken = apiToken return data } func readArgConfig(data *Data) *Data { parser := argparse.NewParser("CommentCI", "Sent a comment to GitHub PR or Issue from your CI") - ghro := parser.String("o", "github-owner", &argparse.Options{ + repoOwner := parser.String("o", "owner", &argparse.Options{ Required: true, Help: "Owner of the repository. User/Organisations.", }) - ghrn := parser.String("r", "github-repository", &argparse.Options{ + repoName := parser.String("r", "repository", &argparse.Options{ Required: true, - Help: "Name of the github repository.", + Help: "Name of the repository.", }) - cmt := parser.String("s", "single-comment", &argparse.Options{ + singleComment := parser.String("s", "single-comment", &argparse.Options{ Required: false, Help: "Single comment string to sent to GitHub.", }) - csm := parser.Flag("c", "codify", &argparse.Options{ + codifyFlag := parser.Flag("c", "codify", &argparse.Options{ Required: false, - Help: "Put comments to the Markdown code block.", + Help: "Put comment to the Markdown code block.", }) - fList := parser.StringList("f", "file", &argparse.Options{ + fileList := parser.StringList("f", "file", &argparse.Options{ Required: false, Help: "By repeating this flag you can specify multiple files which content will be sent to comment.", }) - fCmt := parser.StringList("l", "file-comment", &argparse.Options{ + fileComments := parser.StringList("l", "file-comment", &argparse.Options{ Required: false, - Help: "By repeating this flag you can specify comments for provided files in according order.", + Help: "By repeating this flag you can specify comment for provided files in according order.", }) - isn := parser.Int("i", "issue-number", &argparse.Options{ + issueNumber := parser.Int("i", "issue-number", &argparse.Options{ Required: true, Help: "Number(id) of the Issue/PR to sent a comment.", }) - mcm := parser.Flag("m", "multi-comment", &argparse.Options{ + multiCommentFlag := parser.Flag("m", "multi-comment", &argparse.Options{ Required: false, Default: false, Help: "Put each file into a separate comment in GitHub.", }) + platformType := parser.Selector("p", "platform", []string{"github", "gitlab"}, &argparse.Options{ + Required: true, + Help: "Select platform where to send comment", + }) + targetType := parser.Selector("g", "target-type", []string{"issue", "merge-request"}, &argparse.Options{ + Required: false, + Help: "Select type of comment target (GitLab only)", + }) err := parser.Parse(os.Args) if err != nil { log.Println(err.Error()) } - data.GitHubRepoOwner = *ghro - data.GitHubRepoName = *ghrn - data.CommentText = *cmt - data.CodeStyleMode = *csm - data.FileList = *fList - data.CommentFiles = *fCmt - data.IssueNumber = *isn - data.MultiCommentMode = *mcm + data.RepoOwner = *repoOwner + data.RepoName = *repoName + data.CommentText = *singleComment + data.CodeStyleMode = *codifyFlag + data.FileList = *fileList + data.CommentFiles = *fileComments + data.IssueNumber = *issueNumber + data.MultiCommentMode = *multiCommentFlag + data.Platform = *platformType + data.TargetType = *targetType return data } diff --git a/internal/format/format.go b/internal/format/format.go new file mode 100644 index 0000000..883f194 --- /dev/null +++ b/internal/format/format.go @@ -0,0 +1,34 @@ +package format + +func CodifyText(text string) string { + return "```\n" + text + "\n```\n" +} + +func appendComment(text string, comment string) string { + return comment + "\n" + text + "\n" +} + +func Comment(text string, comment string, codify bool) string { + if codify == true { + return appendComment(CodifyText(text), comment) + } + return appendComment(text, comment) +} + +func SingleComment(rawText []string, rawComment []string, codify bool) string { + if len(rawText) == 1 { + if len(rawComment) > 0 { + return Comment(rawText[0], rawComment[0], codify) + } + return Comment(rawText[0], "", codify) + } + var result string + for i, t := range rawText { + if i >= len(rawComment) { + result += Comment(t, "", codify) + } else { + result += Comment(t, rawComment[i], codify) + } + } + return result +} diff --git a/internal/comments/comments_test.go b/internal/format/format_test.go similarity index 79% rename from internal/comments/comments_test.go rename to internal/format/format_test.go index 98077bc..96e270f 100644 --- a/internal/comments/comments_test.go +++ b/internal/format/format_test.go @@ -1,14 +1,13 @@ -package comments_test +package format import ( - "github.com/ThelonKarrde/CommentCI/internal/comments" "testing" ) func TestCodifyTest(t *testing.T) { testString := "comment" rString := "```\ncomment\n```\n" - codifiedString := comments.CodifyText(testString) + codifiedString := CodifyText(testString) if codifiedString != rString { t.Error("Fail to codify string! " + codifiedString) } @@ -18,7 +17,7 @@ func TestAppendComment(t *testing.T) { text := "text" comment := "comment" rString := "comment\ntext\n" - cmtString := comments.AppendComment(text, comment) + cmtString := appendComment(text, comment) if cmtString != rString { t.Error("Fail to attach comment! " + cmtString) } @@ -28,7 +27,7 @@ func TestMakeCommentNoCodify(t *testing.T) { text := "text" comment := "comment" rString := "comment\ntext\n" - cmtString := comments.MakeComment(text, comment, false) + cmtString := Comment(text, comment, false) if cmtString != rString { t.Error("Fail to make a comment without codify! " + cmtString) } @@ -38,7 +37,7 @@ func TestMakeCommentWithCodify(t *testing.T) { text := "text" comment := "comment" rString := "comment\n```\ntext\n```\n\n" - cmtString := comments.MakeComment(text, comment, true) + cmtString := Comment(text, comment, true) if cmtString != rString { t.Error("Fail to make a comment with codify! Real: " + cmtString + " Desired: " + rString) } @@ -49,7 +48,7 @@ func TestMakeSingleCommentMText(t *testing.T) { cmts := []string{"comment1", "comment2"} rString := "comment1\ntext1\ncomment2\ntext2\n" - cmtString := comments.MakeSingleComment(texts, cmts, false) + cmtString := SingleComment(texts, cmts, false) if cmtString != rString { t.Error("Fail to make a single comment with codify! Real: " + cmtString + " Desired: " + rString) } @@ -60,7 +59,7 @@ func TestMakeSingleCommentSText(t *testing.T) { cmts := []string{"comment1"} rString := "comment1\ntext1\n" - cmtString := comments.MakeSingleComment(texts, cmts, false) + cmtString := SingleComment(texts, cmts, false) if cmtString != rString { t.Error("Fail to make a single comment with codify! Real: " + cmtString + " Desired: " + rString) } @@ -71,7 +70,7 @@ func TestMakeSingleCommentSTextNoComment(t *testing.T) { var cmts []string rString := "\ntext1\n" - cmtString := comments.MakeSingleComment(texts, cmts, false) + cmtString := SingleComment(texts, cmts, false) if cmtString != rString { t.Error("Fail to make a single comment without codify and no comments! Real: " + cmtString + " Desired: " + rString) } @@ -82,7 +81,7 @@ func TestMakeSingleCommentMTextNoComment(t *testing.T) { var cmts []string rString := "\ntext1\n\ntext2\n" - cmtString := comments.MakeSingleComment(texts, cmts, false) + cmtString := SingleComment(texts, cmts, false) if cmtString != rString { t.Error("Fail to make a single comment without codify and no comments! Real: " + cmtString + " Desired: " + rString) } @@ -93,7 +92,7 @@ func TestMakeSingleCommentMTextSComments(t *testing.T) { cmts := []string{"comment1"} rString := "comment1\ntext1\n\ntext2\n" - cmtString := comments.MakeSingleComment(texts, cmts, false) + cmtString := SingleComment(texts, cmts, false) if cmtString != rString { t.Error("Fail to make a single comment without codify and 2/1 text comments! Real: " + cmtString + " Desired: " + rString) } diff --git a/internal/github/github.go b/internal/github/github.go index 828e98d..ac35a12 100644 --- a/internal/github/github.go +++ b/internal/github/github.go @@ -8,7 +8,7 @@ import ( "net/http" ) -func createGithubToken(accessToken string) (context.Context, *http.Client) { +func createOauthClient(accessToken string) (context.Context, *http.Client) { ctx := context.Background() ts := oauth2.StaticTokenSource( &oauth2.Token{AccessToken: accessToken}, @@ -16,11 +16,11 @@ func createGithubToken(accessToken string) (context.Context, *http.Client) { return ctx, oauth2.NewClient(ctx, ts) } -func CommentIssue(comment *string, accessToken string, owner string, repo string, issue int) { - ctx, token := createGithubToken(accessToken) - ghClient := github.NewClient(token) - ghCmt := github.IssueComment{Body: comment} - _, _, err := ghClient.Issues.CreateComment(ctx, owner, repo, issue, &ghCmt) +func Comment(commentText *string, accessToken string, owner string, repo string, issue int) { + ctx, oauthClient := createOauthClient(accessToken) + client := github.NewClient(oauthClient) + comment := github.IssueComment{Body: commentText} + _, _, err := client.Issues.CreateComment(ctx, owner, repo, issue, &comment) if err != nil { log.Fatalf(err.Error()) } diff --git a/internal/gitlab/gitlab.go b/internal/gitlab/gitlab.go new file mode 100644 index 0000000..e3cfaad --- /dev/null +++ b/internal/gitlab/gitlab.go @@ -0,0 +1,37 @@ +package gitlab + +import ( + gogitlab "github.com/xanzy/go-gitlab" + "log" +) + +func createClient(apiToken string) *gogitlab.Client { + client, err := gogitlab.NewClient(apiToken) + if err != nil { + log.Fatalf("Failed to create client: %v", err) + } + return client +} + +func makePid(owner string, repo string) string { + return owner + "/" + repo +} + +func Comment(cmType string, comment *string, apiToken string, owner string, repo string, id int) { + git := createClient(apiToken) + pid := makePid(owner, repo) + var err error + switch cmType { + case "issue": + cmtOpts := gogitlab.CreateIssueNoteOptions{Body: comment} + _, _, err = git.Notes.CreateIssueNote(pid, id, &cmtOpts) + case "merge-request": + cmtOpts := gogitlab.CreateMergeRequestNoteOptions{Body: comment} + _, _, err = git.Notes.CreateMergeRequestNote(pid, id, &cmtOpts) + default: + log.Fatalf("No target type sepcified for GitLab mode!") + } + if err != nil { + log.Fatalf("Failt to create %s comment: %v", cmType, err) + } +} diff --git a/internal/utils/utils_test.go b/internal/utils/utils_test.go index bf79a65..891a1fe 100644 --- a/internal/utils/utils_test.go +++ b/internal/utils/utils_test.go @@ -2,7 +2,6 @@ package utils_test import ( "github.com/ThelonKarrde/CommentCI/internal/utils" - "io/ioutil" "log" "os" "testing" @@ -11,7 +10,7 @@ import ( func TestReadFileToString(t *testing.T) { testString := "test content" content := []byte(testString) - tmpfile, err := ioutil.TempFile("", "test") + tmpfile, err := os.CreateTemp("", "test") if err != nil { log.Fatal(err) } @@ -30,12 +29,12 @@ func TestReadFileToString(t *testing.T) { func TestConvertFilesToStrings(t *testing.T) { testStrings := [2]string{"test content 1", "test content 2"} - tmp1, err := ioutil.TempFile("", "test1") + tmp1, err := os.CreateTemp("", "test1") if err != nil { log.Fatal(err) } defer os.Remove(tmp1.Name()) - tmp2, err := ioutil.TempFile("", "test2") + tmp2, err := os.CreateTemp("", "test2") if err != nil { log.Fatal(err) }