Compare commits
322 Commits
status-cod
...
main
Author | SHA1 | Date |
---|---|---|
LinXiaoWei | bffc1a0989 | 1 year ago |
包子 | 32b1d13f90 | 1 year ago |
dependabot[bot] | db2a565d1c | 1 year ago |
jessetang | fcd3b18e83 | 1 year ago |
freezeChen | 3445f3ea8e | 1 year ago |
Tony Chen | 32c0d2dd97 | 1 year ago |
xu0o0 | e86ad248c3 | 1 year ago |
liaochuntao | 69d73225a9 | 1 year ago |
Fengbin Shi | 49ffd95a0c | 1 year ago |
haiyux | 96480c11ee | 2 years ago |
dependabot[bot] | 1d50f50262 | 2 years ago |
dependabot[bot] | 6d741828c2 | 2 years ago |
Xudong Cai | 4a56b5669d | 2 years ago |
包子 | 56777ee655 | 2 years ago |
dependabot[bot] | b1cd1d3cf8 | 2 years ago |
dependabot[bot] | 37a521d59f | 2 years ago |
dependabot[bot] | 6cf407b9bd | 2 years ago |
dependabot[bot] | a904794546 | 2 years ago |
chen quan | a837603c6d | 2 years ago |
dependabot[bot] | 0b1fdbe51c | 2 years ago |
dependabot[bot] | 81988e6a85 | 2 years ago |
Haibo | 1f10166028 | 2 years ago |
dependabot[bot] | c6a4604839 | 2 years ago |
Bin | aed172b8dd | 2 years ago |
dependabot[bot] | 520b321fe9 | 2 years ago |
ibrahim albarghouthi | 3958f9d5c0 | 2 years ago |
dependabot[bot] | e9870cb48f | 2 years ago |
dependabot[bot] | f8c19c37af | 2 years ago |
woniu317 | d0847cd462 | 2 years ago |
jessetang | f03f5f8988 | 2 years ago |
jessetang | d470886977 | 2 years ago |
Bin | 446774f9e5 | 2 years ago |
yonwoo9 | e273c5188a | 2 years ago |
jessetang | 393bf4dbcb | 2 years ago |
虫子樱桃 | 6a4d17d79a | 2 years ago |
Bin | 99ccd00434 | 2 years ago |
dependabot[bot] | f47a238478 | 2 years ago |
dependabot[bot] | 3d1af9af38 | 2 years ago |
jessetang | 9a973d29c2 | 2 years ago |
jessetang | 0c2d2632ac | 2 years ago |
包子 | 78a2089f2b | 2 years ago |
Xin | d05729399e | 2 years ago |
包子 | 8af9ca33bd | 2 years ago |
dependabot[bot] | bd26120ec6 | 2 years ago |
jessetang | 6369db2e8e | 2 years ago |
jessetang | 492248d032 | 2 years ago |
虫子樱桃 | ae4dd7f4a8 | 2 years ago |
包子 | 33cb4576e9 | 2 years ago |
包子 | 768ffd71d4 | 2 years ago |
jessetang | 9ee4fcb48a | 2 years ago |
jessetang | ae2dcb04c0 | 2 years ago |
Xin | 6602dc325e | 2 years ago |
包子 | 7eca8f8034 | 2 years ago |
yonwoo9 | 665a72e67f | 2 years ago |
包子 | a672980a15 | 2 years ago |
dependabot[bot] | 51fac4ff90 | 2 years ago |
dependabot[bot] | 9c7182058e | 2 years ago |
dependabot[bot] | 91be9c1071 | 2 years ago |
dependabot[bot] | a11002d7ee | 2 years ago |
dependabot[bot] | 15de2007c7 | 2 years ago |
dependabot[bot] | 1579155a2c | 2 years ago |
dependabot[bot] | 51a34df0a6 | 2 years ago |
dependabot[bot] | 61176708e6 | 2 years ago |
dependabot[bot] | b79c142580 | 2 years ago |
dependabot[bot] | f458e2535f | 2 years ago |
dependabot[bot] | 8203a90047 | 2 years ago |
dependabot[bot] | c65f823c38 | 2 years ago |
dependabot[bot] | a6c9fdd9d3 | 2 years ago |
dependabot[bot] | 7e89bbd799 | 2 years ago |
包子 | 834b781ee2 | 2 years ago |
hoslo | 19f008b483 | 2 years ago |
180909 | e4595db3d8 | 2 years ago |
dependabot[bot] | e33d644a78 | 2 years ago |
180909 | d8d231e725 | 2 years ago |
weetime | bab67facad | 2 years ago |
thinkgo | d0b1d84850 | 2 years ago |
dependabot[bot] | 54f19c1dcb | 2 years ago |
dependabot[bot] | 8d5010495a | 2 years ago |
jessetang | 6330a5688e | 2 years ago |
包子 | 27eadd83b4 | 2 years ago |
YuanXin Hu | 0a076443cb | 2 years ago |
aveyuan | 7def38acde | 2 years ago |
LiuDui | 77abb6356f | 2 years ago |
包子 | 50da181d69 | 2 years ago |
包子 | a006328db6 | 2 years ago |
leyou240 | 613282b096 | 2 years ago |
LiuDui | 08f37391e1 | 2 years ago |
cui fliter | 239121155d | 2 years ago |
jerjjj | b242403bc1 | 2 years ago |
Kevin Wan | 63b23af418 | 2 years ago |
liyaopinner | 35800916dc | 2 years ago |
longxboy | bebea0c103 | 2 years ago |
虫子樱桃 | 61744753eb | 2 years ago |
桂后昌 | b2689af39c | 2 years ago |
180909 | e22775cfcc | 2 years ago |
cui fliter | 9cc1047c75 | 2 years ago |
包子 | 7e896ae4c0 | 2 years ago |
包子 | 33d51a84c3 | 2 years ago |
longxboy | eafbe908a8 | 2 years ago |
dependabot[bot] | f49ac647e8 | 2 years ago |
baeNewJeans | 65c51594f9 | 2 years ago |
包子 | 480b16b817 | 2 years ago |
dependabot[bot] | b26023888d | 2 years ago |
刘思圆 | a3f24ee704 | 2 years ago |
Remember | 271b6c2924 | 2 years ago |
Luckystar | c442a320a0 | 2 years ago |
soukengo | b0db594829 | 2 years ago |
dependabot[bot] | 33fff02a62 | 2 years ago |
Juan C. Yamacho H | d12498ed38 | 2 years ago |
虫子樱桃 | 852a77faa6 | 2 years ago |
dependabot[bot] | 6f78ccacd9 | 2 years ago |
dependabot[bot] | 2c3fab50a3 | 2 years ago |
dependabot[bot] | 2a9808df14 | 2 years ago |
dependabot[bot] | 89d8eeba62 | 2 years ago |
dependabot[bot] | a017ab0957 | 2 years ago |
baozhecheng | a45f3afdff | 2 years ago |
baozhecheng | b67d514bfa | 2 years ago |
Xingwang Liu | facafba64a | 2 years ago |
baozhecheng | e36612e9ca | 2 years ago |
虫子樱桃 | 3d322fe6c1 | 2 years ago |
woniu317 | 2cf82fa4a7 | 2 years ago |
jessetang | 3393990cd8 | 2 years ago |
dependabot[bot] | 3c3829795c | 2 years ago |
Ccheers | 8732b76386 | 2 years ago |
Aurélien Perrier | d779faf091 | 2 years ago |
qshuai | a82c82d49f | 2 years ago |
180909 | c530d63e75 | 2 years ago |
包子 | a7bae93ee0 | 2 years ago |
dependabot[bot] | b339ae8956 | 2 years ago |
dependabot[bot] | 3f698aa2c0 | 2 years ago |
dependabot[bot] | c5888ff464 | 2 years ago |
dependabot[bot] | 878eca54ab | 2 years ago |
yeqown | 275f815e40 | 2 years ago |
Cluas | 383f28faeb | 2 years ago |
dependabot[bot] | e9ef3eea2d | 2 years ago |
dependabot[bot] | 58d9e3be56 | 2 years ago |
dependabot[bot] | 818452dd53 | 2 years ago |
dependabot[bot] | 699f0304ed | 2 years ago |
dependabot[bot] | c888d50cc5 | 2 years ago |
jessetang | a1a2b9dbd9 | 2 years ago |
JellyTony | 590c469081 | 2 years ago |
Miguel Martínez Triviño | 0f38511ea8 | 2 years ago |
jessetang | 511f1917ce | 2 years ago |
jessetang | 2a65502be2 | 2 years ago |
dependabot[bot] | 03d9494b19 | 2 years ago |
dependabot[bot] | c4c1ebab47 | 2 years ago |
Tony Chen | f0878b0a78 | 2 years ago |
jessetang | 3c65f16737 | 2 years ago |
包子 | dcae38d656 | 2 years ago |
Jesse | a911f8f9ee | 2 years ago |
dependabot[bot] | 4bd1fde7ef | 2 years ago |
Jesse | 54655e4b24 | 2 years ago |
Tony Chen | 185aaa7184 | 2 years ago |
Guoqiang Ding | 40300677ee | 2 years ago |
Jesse | 6bb3ad6f27 | 2 years ago |
Jesse | 54c6fb3631 | 2 years ago |
Jesse | b5482d1794 | 2 years ago |
Guoqiang Ding | e3feea6eeb | 2 years ago |
ruohone | d82d607c21 | 2 years ago |
jesse.tang | 7a99e8bbdc | 2 years ago |
jesse.tang | 77d260241c | 2 years ago |
jesse.tang | 2de6ba028c | 2 years ago |
jesse.tang | b5cd1c693d | 2 years ago |
jesse.tang | c5e86ca36d | 2 years ago |
包子 | 8743f3e50c | 2 years ago |
jesse.tang | 69fcd50c0a | 2 years ago |
jesse.tang | 9f65c1a03d | 2 years ago |
Tony Chen | a680321309 | 2 years ago |
Tony Chen | 468630cc4b | 2 years ago |
180909 | 9301bfa407 | 2 years ago |
leyou240 | ff59a89b06 | 2 years ago |
jesse.tang | 0ecc2b422f | 2 years ago |
Gaffey | faa3adc300 | 2 years ago |
180909 | b10e067fe9 | 2 years ago |
jesse.tang | 0e698b248a | 2 years ago |
180909 | 2936b5ba80 | 2 years ago |
jesse.tang | 4d95050747 | 2 years ago |
swliao425 | 8d067a32db | 2 years ago |
180909 | 2170a12aa4 | 2 years ago |
180909 | add67beeb3 | 2 years ago |
包子 | 7866ff75fd | 2 years ago |
Tony Chen | 2d325fd386 | 2 years ago |
jesse.tang | 080165f2ee | 2 years ago |
jesse.tang | 9737a3c5e4 | 2 years ago |
Jiepeng Cao | 7f2666be9f | 2 years ago |
jesse.tang | 7a320233cd | 2 years ago |
Loner1024 | d3f80c1061 | 2 years ago |
jesse.tang | b0b49be383 | 2 years ago |
jesse.tang | 0ed01efdfd | 2 years ago |
jesse.tang | f2a33929d0 | 2 years ago |
包子 | ae505063fe | 2 years ago |
Guoqiang Ding | 667d63839c | 2 years ago |
hshe | e176ddfcdd | 2 years ago |
180909 | 0f0c75e20b | 2 years ago |
180909 | 18c5734930 | 2 years ago |
180909 | 8d76eebf8b | 2 years ago |
GongGuoWei | cb69bf3714 | 2 years ago |
黄仲辉 | 617ee1aa39 | 2 years ago |
180909 | 39536d3279 | 2 years ago |
dependabot[bot] | e820b392e9 | 2 years ago |
dependabot[bot] | aaabd07474 | 2 years ago |
dependabot[bot] | 7a336ca353 | 2 years ago |
dependabot[bot] | 503efd3825 | 2 years ago |
icylight | 60b00c8ade | 2 years ago |
Wang-TaoTao | ad7597c0b1 | 2 years ago |
icylight | cbfb6db9cf | 2 years ago |
虫子樱桃 | 20c2425c18 | 2 years ago |
包子 | 890bc21ac1 | 2 years ago |
川桑 | 361391732b | 2 years ago |
包子 | b354f185c0 | 2 years ago |
jesse.tang | 73a8323ee7 | 2 years ago |
Germiniku | cb6176dbbb | 2 years ago |
过客龙门 | 0ce9e8d069 | 2 years ago |
dependabot[bot] | b1bb0bd18f | 2 years ago |
dependabot[bot] | 869fcd57c8 | 2 years ago |
icylight | 5c3f0aa73e | 2 years ago |
jesse.tang | 6ca225b078 | 2 years ago |
YidaZhou | ba72230477 | 2 years ago |
Astone | 205aa88d86 | 2 years ago |
pwli | bdfeb4bf78 | 2 years ago |
haiyux | 39796ea0dc | 2 years ago |
包子 | 563ad0d34a | 2 years ago |
包子 | 3f31b4d734 | 2 years ago |
Tony Chen | 2d206076f8 | 2 years ago |
Germiniku | de2f93fbec | 2 years ago |
longxboy | 11cd43e3c3 | 2 years ago |
kkf1 | d11c6892b4 | 2 years ago |
Haibo | 6d665c0ce6 | 2 years ago |
包子 | 84235462b7 | 2 years ago |
SeniorPlayer | b9b7888d51 | 2 years ago |
realityone | f0c2a6ed90 | 2 years ago |
Weizhen Wang | 57dee517e5 | 2 years ago |
Kagaya | e4d73db523 | 2 years ago |
dependabot[bot] | 0aa9719e3a | 2 years ago |
shifengbin | c407afc81d | 2 years ago |
Germiniku | fea863e783 | 2 years ago |
林晓炜 | 1f3ac4ea22 | 2 years ago |
dependabot[bot] | aae0339692 | 2 years ago |
包子 | eff368621f | 2 years ago |
kiripeng | a5eb913aa0 | 2 years ago |
180909 | ffa1c2696c | 2 years ago |
dependabot[bot] | 86eba94646 | 2 years ago |
dependabot[bot] | 2951b420f1 | 2 years ago |
Tony Chen | f3b0da3f04 | 2 years ago |
dependabot[bot] | 377356d04d | 2 years ago |
dependabot[bot] | 247a74e631 | 2 years ago |
Tony Chen | 3c54997dd8 | 2 years ago |
dependabot[bot] | e6767bc612 | 2 years ago |
dependabot[bot] | 9d24dac487 | 2 years ago |
dependabot[bot] | e2c1fd7489 | 2 years ago |
hshe | b7422717cf | 2 years ago |
Haibo | 59b758ceda | 2 years ago |
林晓炜 | 246d8d9c28 | 2 years ago |
Paul | 92b3c8f94a | 2 years ago |
haiyux | 14cfd65b62 | 2 years ago |
wangcong | 82dfb955f5 | 2 years ago |
风雨雾凇 | de0e4e2228 | 2 years ago |
dependabot[bot] | 1ab3d8f028 | 2 years ago |
dependabot[bot] | 0ff80e42e7 | 2 years ago |
Walrus Yu | d1da8aa1ae | 2 years ago |
shengzhou | ede5f889d4 | 2 years ago |
rogerogers | bcef2b8e3f | 2 years ago |
jakezhu9 | 85af73a84b | 2 years ago |
包子 | 1451b9e0c0 | 2 years ago |
潘雄 | 96c8de9bc4 | 2 years ago |
Tony Chen | d0a0edf67b | 2 years ago |
jakezhu9 | afd108cdc7 | 2 years ago |
Ccheers | b3eff576ce | 2 years ago |
rogerogers | 63827466a3 | 2 years ago |
freezeChen | 187c65bf8c | 2 years ago |
Tony Chen | 6ac63e6439 | 2 years ago |
Tony Chen | c90eab4577 | 2 years ago |
川桑 | 102391165e | 2 years ago |
Giovanny Gutiérrez | 2209da5e24 | 2 years ago |
dependabot[bot] | 1ea4ef7412 | 2 years ago |
川桑 | d88052b7dd | 2 years ago |
darkweak | c9fbb27b5b | 2 years ago |
shengzhou | dec323113f | 2 years ago |
dependabot[bot] | 8d0d7838ca | 2 years ago |
rogerogers | 2525e81e55 | 2 years ago |
dependabot[bot] | 08fccfcb66 | 2 years ago |
dependabot[bot] | 8e9e15e04b | 2 years ago |
Betula-L | e09d294388 | 2 years ago |
dependabot[bot] | 39bfeeb2f7 | 2 years ago |
Y.Horie | 106bc07def | 2 years ago |
Tony Chen | 0bcdb8d59c | 2 years ago |
shengzhou | 5df19c47d8 | 2 years ago |
Loner1024 | 62b58848d6 | 2 years ago |
dependabot[bot] | b6954d1aeb | 2 years ago |
rogerogers | 6c36cc9544 | 2 years ago |
wangcong | 20b7c9f4d7 | 2 years ago |
haiyux | addcbba66e | 2 years ago |
Guoqiang Ding | 035c2f5387 | 2 years ago |
rogerogers | 8c0a354797 | 2 years ago |
freezeChen | ed8b2352b7 | 2 years ago |
liuyi0618 | 52031f1381 | 2 years ago |
Y.Horie | 9015ffb920 | 2 years ago |
ThereWeGo | 4ca25e4679 | 2 years ago |
shifengbin | 2ad7ffdd7e | 2 years ago |
zoujiejun | 3905182e98 | 2 years ago |
Ccheers | 13c33fc4d3 | 2 years ago |
haiyux | 25c5996360 | 2 years ago |
Guoqiang Ding | 2f8703bff2 | 2 years ago |
charviki | a3439c9713 | 2 years ago |
Tony Chen | a0e624c0b8 | 2 years ago |
Cluas | 6fa5700c3c | 2 years ago |
包子 | 3aaac45e3d | 2 years ago |
longxboy | 2a989ea0fe | 2 years ago |
YuanXin Hu | e3c37b936f | 2 years ago |
Cluas | 4f8d8ef8da | 2 years ago |
haiyux | 752f011ba1 | 2 years ago |
raw34 | 228ceaae9d | 2 years ago |
包子 | 4b7afe52af | 2 years ago |
longxboy | 123fc1e6c8 | 2 years ago |
longxboy | eb280903f0 | 2 years ago |
longxboy | 93adaba60a | 2 years ago |
包子 | 874d4c3edc | 2 years ago |
workman-Lu | d1550b366b | 2 years ago |
虫子樱桃 | c6f6caa887 | 2 years ago |
包子 | 95dce00852 | 2 years ago |
haiyux | ad5e9032a3 | 2 years ago |
Tony Chen | 1b3529fd0b | 2 years ago |
@ -0,0 +1,12 @@ |
||||
daysUntilStale: 30 |
||||
daysUntilClose: 3 |
||||
exemptLabels: |
||||
- pinned |
||||
- security |
||||
- bug |
||||
staleLabel: wontfix |
||||
markComment: > |
||||
This issue has been automatically marked as stale because it has not had |
||||
recent activity. It will be closed if no further activity occurs. Thank you |
||||
for your contributions. |
||||
closeComment: true |
@ -0,0 +1,58 @@ |
||||
package base |
||||
|
||||
import ( |
||||
"errors" |
||||
"net/url" |
||||
"regexp" |
||||
"strings" |
||||
) |
||||
|
||||
var ( |
||||
scpSyntaxRe = regexp.MustCompile(`^(\w+)@([\w.-]+):(.*)$`) |
||||
scheme = []string{"git", "https", "http", "git+ssh", "ssh", "file", "ftp", "ftps"} |
||||
) |
||||
|
||||
// ParseVCSUrl ref https://github.com/golang/go/blob/master/src/cmd/go/internal/vcs/vcs.go
|
||||
// see https://go-review.googlesource.com/c/go/+/12226/
|
||||
// git url define https://git-scm.com/docs/git-clone#_git_urls
|
||||
func ParseVCSUrl(repo string) (*url.URL, error) { |
||||
var ( |
||||
repoURL *url.URL |
||||
err error |
||||
) |
||||
|
||||
if m := scpSyntaxRe.FindStringSubmatch(repo); m != nil { |
||||
// Match SCP-like syntax and convert it to a URL.
|
||||
// Eg, "git@github.com:user/repo" becomes
|
||||
// "ssh://git@github.com/user/repo".
|
||||
repoURL = &url.URL{ |
||||
Scheme: "ssh", |
||||
User: url.User(m[1]), |
||||
Host: m[2], |
||||
Path: m[3], |
||||
} |
||||
} else { |
||||
if !strings.Contains(repo, "//") { |
||||
repo = "//" + repo |
||||
} |
||||
if strings.HasPrefix(repo, "//git@") { |
||||
repo = "ssh:" + repo |
||||
} else if strings.HasPrefix(repo, "//") { |
||||
repo = "https:" + repo |
||||
} |
||||
repoURL, err = url.Parse(repo) |
||||
if err != nil { |
||||
return nil, err |
||||
} |
||||
} |
||||
|
||||
// Iterate over insecure schemes too, because this function simply
|
||||
// reports the state of the repo. If we can't see insecure schemes then
|
||||
// we can't report the actual repo URL.
|
||||
for _, s := range scheme { |
||||
if repoURL.Scheme == s { |
||||
return repoURL, nil |
||||
} |
||||
} |
||||
return nil, errors.New("unable to parse repo url") |
||||
} |
@ -0,0 +1,55 @@ |
||||
package base |
||||
|
||||
import ( |
||||
"net" |
||||
"strings" |
||||
"testing" |
||||
) |
||||
|
||||
func TestParseVCSUrl(t *testing.T) { |
||||
repos := []string{ |
||||
// ssh://[user@]host.xz[:port]/path/to/repo.git/
|
||||
"ssh://git@github.com:7875/go-kratos/kratos.git", |
||||
// git://host.xz[:port]/path/to/repo.git/
|
||||
"git://github.com:7875/go-kratos/kratos.git", |
||||
// http[s]://host.xz[:port]/path/to/repo.git/
|
||||
"https://github.com:7875/go-kratos/kratos.git", |
||||
// ftp[s]://host.xz[:port]/path/to/repo.git/
|
||||
"ftps://github.com:7875/go-kratos/kratos.git", |
||||
//[user@]host.xz:path/to/repo.git/
|
||||
"git@github.com:go-kratos/kratos.git", |
||||
// ssh://[user@]host.xz[:port]/~[user]/path/to/repo.git/
|
||||
"ssh://git@github.com:7875/go-kratos/kratos.git", |
||||
// git://host.xz[:port]/~[user]/path/to/repo.git/
|
||||
"git://github.com:7875/go-kratos/kratos.git", |
||||
//[user@]host.xz:/~[user]/path/to/repo.git/
|
||||
"git@github.com:go-kratos/kratos.git", |
||||
///path/to/repo.git/
|
||||
"~/go-kratos/kratos.git", |
||||
// file:///path/to/repo.git/
|
||||
"file://~/go-kratos/kratos.git", |
||||
} |
||||
for _, repo := range repos { |
||||
url, err := ParseVCSUrl(repo) |
||||
if err != nil { |
||||
t.Fatal(repo, err) |
||||
} |
||||
urlPath := strings.TrimLeft(url.Path, "/") |
||||
if urlPath != "go-kratos/kratos.git" { |
||||
t.Fatal(repo, "parse url failed", urlPath) |
||||
} |
||||
} |
||||
} |
||||
|
||||
func TestParseSsh(t *testing.T) { |
||||
repo := "ssh://git@github.com:7875/go-kratos/kratos.git" |
||||
url, err := ParseVCSUrl(repo) |
||||
if err != nil { |
||||
t.Fatal(err) |
||||
} |
||||
host, _, err := net.SplitHostPort(url.Host) |
||||
if err != nil { |
||||
host = url.Host |
||||
} |
||||
t.Log(host, url.Path) |
||||
} |
@ -0,0 +1,25 @@ |
||||
package change |
||||
|
||||
import "testing" |
||||
|
||||
func TestParseGithubURL(t *testing.T) { |
||||
urls := []struct { |
||||
url string |
||||
owner string |
||||
repo string |
||||
}{ |
||||
{"https://github.com/go-kratos/kratos.git", "go-kratos", "kratos"}, |
||||
{"https://github.com/go-kratos/kratos", "go-kratos", "kratos"}, |
||||
{"git@github.com:go-kratos/kratos.git", "go-kratos", "kratos"}, |
||||
{"https://github.com/go-kratos/go-kratos.dev.git", "go-kratos", "go-kratos.dev"}, |
||||
} |
||||
for _, url := range urls { |
||||
owner, repo := ParseGithubURL(url.url) |
||||
if owner != url.owner { |
||||
t.Fatalf("owner want: %s, got: %s", owner, url.owner) |
||||
} |
||||
if repo != url.repo { |
||||
t.Fatalf("repo want: %s, got: %s", repo, url.repo) |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,29 @@ |
||||
//go:build linux
|
||||
// +build linux
|
||||
|
||||
package project |
||||
|
||||
import ( |
||||
"testing" |
||||
) |
||||
|
||||
func Test_processProjectParams(t *testing.T) { |
||||
type args struct { |
||||
projectName string |
||||
fallbackPlaceDir string |
||||
} |
||||
tests := []struct { |
||||
name string |
||||
args args |
||||
want string |
||||
}{ |
||||
{"absLinux", args{projectName: "/home/kratos/awesome/go/demo", fallbackPlaceDir: ""}, "/home/kratos/awesome/go"}, |
||||
} |
||||
for _, tt := range tests { |
||||
t.Run(tt.name, func(t *testing.T) { |
||||
if _, got := processProjectParams(tt.args.projectName, tt.args.fallbackPlaceDir); got != tt.want { |
||||
t.Errorf("processProjectParams() = %v, want %v", got, tt.want) |
||||
} |
||||
}) |
||||
} |
||||
} |
@ -0,0 +1,144 @@ |
||||
package project |
||||
|
||||
import ( |
||||
"fmt" |
||||
"go/parser" |
||||
"go/token" |
||||
"os" |
||||
"path/filepath" |
||||
"testing" |
||||
|
||||
"github.com/go-kratos/kratos/cmd/kratos/v2/internal/base" |
||||
) |
||||
|
||||
// TestCmdNew tests the `kratos new` command.
|
||||
func TestCmdNew(t *testing.T) { |
||||
cwd := changeCurrentDir(t) |
||||
projectName := "helloworld" |
||||
|
||||
// create a new project
|
||||
CmdNew.SetArgs([]string{projectName}) |
||||
if err := CmdNew.Execute(); err != nil { |
||||
t.Fatalf("executing command: %v", err) |
||||
} |
||||
|
||||
// check that the expected files were created
|
||||
for _, file := range []string{ |
||||
"go.mod", |
||||
"go.sum", |
||||
"README.md", |
||||
"cmd/helloworld/main.go", |
||||
} { |
||||
if _, err := os.Stat(filepath.Join(cwd, projectName, file)); err != nil { |
||||
t.Errorf("expected file %s to exist", file) |
||||
} |
||||
} |
||||
|
||||
// check that the go.mod file contains the expected module name
|
||||
assertGoMod(t, filepath.Join(cwd, projectName, "go.mod"), projectName) |
||||
|
||||
assertImportsInclude(t, filepath.Join(cwd, projectName, "cmd", projectName, "wire.go"), fmt.Sprintf(`"%s/internal/biz"`, projectName)) |
||||
} |
||||
|
||||
// TestCmdNewNoMod tests the `kratos new` command with the --nomod flag.
|
||||
func TestCmdNewNoMod(t *testing.T) { |
||||
cwd := changeCurrentDir(t) |
||||
|
||||
// create a new project
|
||||
CmdNew.SetArgs([]string{"project"}) |
||||
if err := CmdNew.Execute(); err != nil { |
||||
t.Fatalf("executing command: %v", err) |
||||
} |
||||
|
||||
// add new app with --nomod flag
|
||||
CmdNew.SetArgs([]string{"--nomod", "project/app/user"}) |
||||
if err := CmdNew.Execute(); err != nil { |
||||
t.Fatalf("executing command: %v", err) |
||||
} |
||||
|
||||
// check that the expected files were created
|
||||
for _, file := range []string{ |
||||
"go.mod", |
||||
"go.sum", |
||||
"README.md", |
||||
"cmd/project/main.go", |
||||
"app/user/cmd/user/main.go", |
||||
} { |
||||
if _, err := os.Stat(filepath.Join(cwd, "project", file)); err != nil { |
||||
t.Errorf("expected file %s to exist", file) |
||||
} |
||||
} |
||||
|
||||
assertImportsInclude(t, filepath.Join(cwd, "project/app/user/cmd/user/wire.go"), `"project/app/user/internal/biz"`) |
||||
} |
||||
|
||||
// assertImportsInclude checks that the file at path contains the expected import.
|
||||
func assertImportsInclude(t *testing.T, path, expected string) { |
||||
t.Helper() |
||||
|
||||
got, err := imports(path) |
||||
if err != nil { |
||||
t.Fatalf("getting imports: %v", err) |
||||
} |
||||
|
||||
for _, imp := range got { |
||||
if imp == expected { |
||||
return |
||||
} |
||||
} |
||||
|
||||
t.Errorf("expected imports to include %s, got %v", expected, got) |
||||
} |
||||
|
||||
// imports returns the imports in the file at path.
|
||||
func imports(path string) ([]string, error) { |
||||
fset := token.NewFileSet() |
||||
f, err := parser.ParseFile(fset, path, nil, parser.ImportsOnly) |
||||
if err != nil { |
||||
return nil, err |
||||
} |
||||
|
||||
imports := make([]string, 0, len(f.Imports)) |
||||
for _, s := range f.Imports { |
||||
imports = append(imports, s.Path.Value) |
||||
} |
||||
|
||||
return imports, nil |
||||
} |
||||
|
||||
// assertGoMod checks that the go.mod file contains the expected module name.
|
||||
func assertGoMod(t *testing.T, path, expected string) { |
||||
t.Helper() |
||||
|
||||
got, err := base.ModulePath(path) |
||||
if err != nil { |
||||
t.Fatalf("getting module path: %v", err) |
||||
} |
||||
|
||||
if got != expected { |
||||
t.Errorf("expected module name %s, got %s", expected, got) |
||||
} |
||||
} |
||||
|
||||
// change the working directory to the tempdir
|
||||
func changeCurrentDir(t *testing.T) string { |
||||
t.Helper() |
||||
|
||||
tmp := t.TempDir() |
||||
|
||||
oldCWD, err := os.Getwd() |
||||
if err != nil { |
||||
t.Fatalf("getting working directory: %v", err) |
||||
} |
||||
|
||||
if err := os.Chdir(tmp); err != nil { |
||||
t.Fatalf("changing working directory: %v", err) |
||||
} |
||||
t.Cleanup(func() { |
||||
if err := os.Chdir(oldCWD); err != nil { |
||||
t.Fatalf("restoring working directory: %v", err) |
||||
} |
||||
}) |
||||
|
||||
return tmp |
||||
} |
@ -0,0 +1,30 @@ |
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
package project |
||||
|
||||
import ( |
||||
"testing" |
||||
) |
||||
|
||||
func Test_processProjectParams(t *testing.T) { |
||||
type args struct { |
||||
projectName string |
||||
fallbackPlaceDir string |
||||
} |
||||
tests := []struct { |
||||
name string |
||||
args args |
||||
want string |
||||
}{ |
||||
{"absWindows", args{projectName: "c:\\kratos\\awesome\\go\\demo", fallbackPlaceDir: ""}, "c:\\kratos\\awesome\\go"}, |
||||
//{"relativeWindows", args{projectName: "/home/kratos/awesome/go/demo", fallbackPlaceDir: ""}, "/home/kratos/awesome/go"},
|
||||
} |
||||
for _, tt := range tests { |
||||
t.Run(tt.name, func(t *testing.T) { |
||||
if _, got := processProjectParams(tt.args.projectName, tt.args.fallbackPlaceDir); got != tt.want { |
||||
t.Errorf("getProjectPlaceDir() = %v, want %v", got, tt.want) |
||||
} |
||||
}) |
||||
} |
||||
} |
@ -0,0 +1,38 @@ |
||||
package add |
||||
|
||||
import "testing" |
||||
|
||||
func TestUnderscoreToUpperCamelCase(t *testing.T) { |
||||
tests := []struct { |
||||
name string |
||||
want string |
||||
}{ |
||||
{ |
||||
name: "hello_world", |
||||
want: "HelloWorld", |
||||
}, |
||||
{ |
||||
name: "v2_kratos_dev", |
||||
want: "V2KratosDev", |
||||
}, |
||||
{ |
||||
name: "www_Google_com", |
||||
want: "WwwGoogleCom", |
||||
}, |
||||
{ |
||||
name: "wwwBaidu_com", |
||||
want: "WwwBaiduCom", |
||||
}, |
||||
{ |
||||
name: "HelloWorld", |
||||
want: "HelloWorld", |
||||
}, |
||||
} |
||||
for _, tt := range tests { |
||||
t.Run(tt.name, func(t *testing.T) { |
||||
if got := toUpperCamelCase(tt.name); got != tt.want { |
||||
t.Errorf("toUpperCamelCase() = %v, want %v", got, tt.want) |
||||
} |
||||
}) |
||||
} |
||||
} |
@ -0,0 +1,102 @@ |
||||
package server |
||||
|
||||
import "testing" |
||||
|
||||
func Test_serviceName(t *testing.T) { |
||||
type args struct { |
||||
str string |
||||
} |
||||
tests := []struct { |
||||
name string |
||||
args args |
||||
want string |
||||
}{ |
||||
{ |
||||
name: "serviceName on lowercase words", |
||||
args: args{str: "helloworld"}, |
||||
want: "Helloworld", |
||||
}, |
||||
{ |
||||
name: "serviceName on uppercase words", |
||||
args: args{str: "HELLOWORLD"}, |
||||
want: "HELLOWORLD", |
||||
}, |
||||
{ |
||||
name: "serviceName on lowercase words with spaces", |
||||
args: args{str: "hello world"}, |
||||
want: "HelloWorld", |
||||
}, |
||||
{ |
||||
name: "serviceName on uppercase words with spaces", |
||||
args: args{str: "HELLO WORLD"}, |
||||
want: "HELLOWORLD", |
||||
}, |
||||
{ |
||||
name: "serviceName on Lower Camel Case words", |
||||
args: args{str: "helloWorld"}, |
||||
want: "HelloWorld", |
||||
}, |
||||
{ |
||||
name: "serviceName on Lower Camel Case words", |
||||
args: args{str: "helloWorld"}, |
||||
want: "HelloWorld", |
||||
}, |
||||
{ |
||||
name: "serviceName on Upper Camel Case words", |
||||
args: args{str: "HelloWorld"}, |
||||
want: "HelloWorld", |
||||
}, |
||||
{ |
||||
name: "serviceName on Upper Camel Case words", |
||||
args: args{str: "hello_world"}, |
||||
want: "HelloWorld", |
||||
}, |
||||
} |
||||
for _, tt := range tests { |
||||
t.Run(tt.name, func(t *testing.T) { |
||||
if got := serviceName(tt.args.str); got != tt.want { |
||||
t.Errorf("serviceName() = %v, want %v", got, tt.want) |
||||
} |
||||
}) |
||||
} |
||||
} |
||||
|
||||
func Test_parametersName(t *testing.T) { |
||||
type args struct { |
||||
name string |
||||
} |
||||
tests := []struct { |
||||
name string |
||||
args args |
||||
want string |
||||
}{ |
||||
{ |
||||
name: "parametersName on not nested", |
||||
args: args{ |
||||
name: "MessageResponse", |
||||
}, |
||||
want: "MessageResponse", |
||||
}, |
||||
{ |
||||
name: "parametersName on One layer of nesting", |
||||
args: args{ |
||||
name: "Message.Response", |
||||
}, |
||||
want: "Message_Response", |
||||
}, |
||||
{ |
||||
name: "parametersName on Two layer of nesting", |
||||
args: args{ |
||||
name: "Message.Message2.Response", |
||||
}, |
||||
want: "Message_Message2_Response", |
||||
}, |
||||
} |
||||
for _, tt := range tests { |
||||
t.Run(tt.name, func(t *testing.T) { |
||||
if got := parametersName(tt.args.name); got != tt.want { |
||||
t.Errorf("parametersName() = %v, want %v", got, tt.want) |
||||
} |
||||
}) |
||||
} |
||||
} |
@ -1,4 +1,4 @@ |
||||
package main |
||||
|
||||
// release is the current kratos tool version.
|
||||
const release = "v2.3.0" |
||||
const release = "v2.6.3" |
||||
|
@ -0,0 +1,17 @@ |
||||
{{ range .Errors }} |
||||
|
||||
{{ if .HasComment }}{{ .Comment }}{{ end -}} |
||||
func Is{{.CamelValue}}(err error) bool { |
||||
if err == nil { |
||||
return false |
||||
} |
||||
e := errors.FromError(err) |
||||
return e.Reason == {{ .Name }}_{{ .Value }}.String() && e.Code == {{ .HTTPCode }} |
||||
} |
||||
|
||||
{{ if .HasComment }}{{ .Comment }}{{ end -}} |
||||
func Error{{ .CamelValue }}(format string, args ...interface{}) *errors.Error { |
||||
return errors.New({{ .HTTPCode }}, {{ .Name }}_{{ .Value }}.String(), fmt.Sprintf(format, args...)) |
||||
} |
||||
|
||||
{{- end }} |
@ -1,4 +1,4 @@ |
||||
package main |
||||
|
||||
// release is the current protoc-gen-go-errors version.
|
||||
const release = "v2.3.0" |
||||
const release = "v2.6.3" |
||||
|
@ -0,0 +1,93 @@ |
||||
{{$svrType := .ServiceType}} |
||||
{{$svrName := .ServiceName}} |
||||
|
||||
{{- range .MethodSets}} |
||||
const Operation{{$svrType}}{{.OriginalName}} = "/{{$svrName}}/{{.OriginalName}}" |
||||
{{- end}} |
||||
|
||||
type {{.ServiceType}}HTTPServer interface { |
||||
{{- range .MethodSets}} |
||||
{{- if ne .Comment ""}} |
||||
{{.Comment}} |
||||
{{- end}} |
||||
{{.Name}}(context.Context, *{{.Request}}) (*{{.Reply}}, error) |
||||
{{- end}} |
||||
} |
||||
|
||||
func Register{{.ServiceType}}HTTPServer(s *http.Server, srv {{.ServiceType}}HTTPServer) { |
||||
r := s.Route("/") |
||||
{{- range .Methods}} |
||||
r.{{.Method}}("{{.Path}}", _{{$svrType}}_{{.Name}}{{.Num}}_HTTP_Handler(srv)) |
||||
{{- end}} |
||||
} |
||||
|
||||
{{range .Methods}} |
||||
func _{{$svrType}}_{{.Name}}{{.Num}}_HTTP_Handler(srv {{$svrType}}HTTPServer) func(ctx http.Context) error { |
||||
return func(ctx http.Context) error { |
||||
var in {{.Request}} |
||||
{{- if .HasBody}} |
||||
if err := ctx.Bind(&in{{.Body}}); err != nil { |
||||
return err |
||||
} |
||||
|
||||
{{- if not (eq .Body "")}} |
||||
if err := ctx.BindQuery(&in); err != nil { |
||||
return err |
||||
} |
||||
{{- end}} |
||||
{{- else}} |
||||
if err := ctx.BindQuery(&in{{.Body}}); err != nil { |
||||
return err |
||||
} |
||||
{{- end}} |
||||
{{- if .HasVars}} |
||||
if err := ctx.BindVars(&in); err != nil { |
||||
return err |
||||
} |
||||
{{- end}} |
||||
http.SetOperation(ctx,Operation{{$svrType}}{{.OriginalName}}) |
||||
h := ctx.Middleware(func(ctx context.Context, req interface{}) (interface{}, error) { |
||||
return srv.{{.Name}}(ctx, req.(*{{.Request}})) |
||||
}) |
||||
out, err := h(ctx, &in) |
||||
if err != nil { |
||||
return err |
||||
} |
||||
reply := out.(*{{.Reply}}) |
||||
return ctx.Result(200, reply{{.ResponseBody}}) |
||||
} |
||||
} |
||||
{{end}} |
||||
|
||||
type {{.ServiceType}}HTTPClient interface { |
||||
{{- range .MethodSets}} |
||||
{{.Name}}(ctx context.Context, req *{{.Request}}, opts ...http.CallOption) (rsp *{{.Reply}}, err error) |
||||
{{- end}} |
||||
} |
||||
|
||||
type {{.ServiceType}}HTTPClientImpl struct{ |
||||
cc *http.Client |
||||
} |
||||
|
||||
func New{{.ServiceType}}HTTPClient (client *http.Client) {{.ServiceType}}HTTPClient { |
||||
return &{{.ServiceType}}HTTPClientImpl{client} |
||||
} |
||||
|
||||
{{range .MethodSets}} |
||||
func (c *{{$svrType}}HTTPClientImpl) {{.Name}}(ctx context.Context, in *{{.Request}}, opts ...http.CallOption) (*{{.Reply}}, error) { |
||||
var out {{.Reply}} |
||||
pattern := "{{.Path}}" |
||||
path := binding.EncodeURL(pattern, in, {{not .HasBody}}) |
||||
opts = append(opts, http.Operation(Operation{{$svrType}}{{.OriginalName}})) |
||||
opts = append(opts, http.PathTemplate(pattern)) |
||||
{{if .HasBody -}} |
||||
err := c.cc.Invoke(ctx, "{{.Method}}", path, in{{.Body}}, &out{{.ResponseBody}}, opts...) |
||||
{{else -}} |
||||
err := c.cc.Invoke(ctx, "{{.Method}}", path, nil, &out{{.ResponseBody}}, opts...) |
||||
{{end -}} |
||||
if err != nil { |
||||
return nil, err |
||||
} |
||||
return &out, err |
||||
} |
||||
{{end}} |
@ -1,4 +1,4 @@ |
||||
package main |
||||
|
||||
// release is the current protoc-gen-go-http version.
|
||||
const release = "v2.3.0" |
||||
const release = "v2.6.3" |
||||
|
@ -0,0 +1,43 @@ |
||||
package file |
||||
|
||||
import ( |
||||
"testing" |
||||
) |
||||
|
||||
func TestFormat(t *testing.T) { |
||||
tests := []struct { |
||||
input string |
||||
expect string |
||||
}{ |
||||
{ |
||||
input: "", |
||||
expect: "", |
||||
}, |
||||
{ |
||||
input: " ", |
||||
expect: "", |
||||
}, |
||||
{ |
||||
input: ".", |
||||
expect: "", |
||||
}, |
||||
{ |
||||
input: "a.", |
||||
expect: "", |
||||
}, |
||||
{ |
||||
input: ".b", |
||||
expect: "b", |
||||
}, |
||||
{ |
||||
input: "a.b", |
||||
expect: "b", |
||||
}, |
||||
} |
||||
for _, v := range tests { |
||||
content := format(v.input) |
||||
if got, want := content, v.expect; got != want { |
||||
t.Errorf("expect %v,got %v", want, got) |
||||
} |
||||
} |
||||
} |
File diff suppressed because it is too large
Load Diff
@ -1,41 +1,13 @@ |
||||
package apollo |
||||
|
||||
import ( |
||||
"encoding/json" |
||||
|
||||
"gopkg.in/yaml.v3" |
||||
|
||||
"github.com/apolloconfig/agollo/v4/constant" |
||||
"github.com/apolloconfig/agollo/v4/extension" |
||||
) |
||||
|
||||
type jsonExtParser struct{} |
||||
|
||||
func (parser jsonExtParser) Parse(configContent interface{}) (map[string]interface{}, error) { |
||||
v, ok := configContent.(string) |
||||
if !ok { |
||||
return nil, nil |
||||
} |
||||
out := make(map[string]interface{}, 4) |
||||
err := json.Unmarshal([]byte(v), &out) |
||||
return out, err |
||||
return map[string]interface{}{"content": configContent}, nil |
||||
} |
||||
|
||||
type yamlExtParser struct{} |
||||
|
||||
func (parser yamlExtParser) Parse(configContent interface{}) (out map[string]interface{}, err error) { |
||||
v, ok := configContent.(string) |
||||
if !ok { |
||||
return nil, nil |
||||
} |
||||
out = make(map[string]interface{}, 4) |
||||
err = yaml.Unmarshal([]byte(v), &out) |
||||
return |
||||
} |
||||
|
||||
func init() { |
||||
// add json/yaml/yml format
|
||||
extension.AddFormatParser(constant.JSON, &jsonExtParser{}) |
||||
extension.AddFormatParser(constant.YAML, &yamlExtParser{}) |
||||
extension.AddFormatParser(constant.YML, &yamlExtParser{}) |
||||
func (parser yamlExtParser) Parse(configContent interface{}) (map[string]interface{}, error) { |
||||
return map[string]interface{}{"content": configContent}, nil |
||||
} |
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue