diff --git a/flags/config.go b/flags/config.go index 9becb12..cb1a9d0 100644 --- a/flags/config.go +++ b/flags/config.go @@ -7,7 +7,7 @@ import ( "go.jolheiser.com/vanity/api" - "github.com/BurntSushi/toml" + "github.com/pelletier/go-toml" "github.com/urfave/cli/v2" "go.jolheiser.com/beaver" ) @@ -44,11 +44,15 @@ func setConfig(ctx *cli.Context) { var cfg tomlConfig if configPath != "" { beaver.Infof("Loading configuration from %s", configPath) - _, err := toml.DecodeFile(configPath, &cfg) + tree, err := toml.LoadFile(configPath) if err != nil { beaver.Errorf("Could not load configuration from %s: %v", configPath, err) return } + if err = tree.Unmarshal(&cfg); err != nil { + beaver.Errorf("Could not unmarshal configuration from %s: %v", configPath, err) + return + } } if !ctx.IsSet("port") && cfg.Port > 0 { diff --git a/flags/flags.go b/flags/flags.go index 767691d..bcc0188 100644 --- a/flags/flags.go +++ b/flags/flags.go @@ -35,6 +35,7 @@ var ( Archive bool Override = make(map[string]string) Interval time.Duration + Manual bool Debug bool ConfigPackages []*api.Package @@ -135,6 +136,12 @@ var Flags = []cli.Flag{ EnvVars: []string{"VANITY_INTERVAL"}, Destination: &Interval, }, + &cli.BoolFlag{ + Name: "manual", + Usage: "Disable cron and only update with endpoint", + EnvVars: []string{"VANITY_MANUAL"}, + Destination: &Manual, + }, &cli.BoolFlag{ Name: "debug", Usage: "Debug logging", @@ -196,6 +203,10 @@ func Before(ctx *cli.Context) error { Exclude[idx] = regexp.MustCompile(e) } + if Manual { + beaver.Info("Running in manual mode") + } + if Debug { beaver.Console.Level = beaver.DEBUG } @@ -213,5 +224,6 @@ func Before(ctx *cli.Context) error { beaver.Debugf("Archive: %t", Archive) beaver.Debugf("Override: %s", override.Value()) beaver.Debugf("Interval: %s", Interval) + beaver.Debugf("Manual: %t", Manual) return nil } diff --git a/go.mod b/go.mod index 5637c84..69289c5 100644 --- a/go.mod +++ b/go.mod @@ -1,16 +1,17 @@ module go.jolheiser.com/vanity -go 1.12 +go 1.16 require ( - code.gitea.io/sdk/gitea v0.12.2 - github.com/BurntSushi/toml v0.3.1 + code.gitea.io/sdk/gitea v0.13.2 github.com/cpuguy83/go-md2man/v2 v2.0.0 // indirect github.com/go-chi/chi v4.1.2+incompatible github.com/google/go-github/v32 v32.1.0 + github.com/pelletier/go-toml v1.8.1 github.com/urfave/cli/v2 v2.2.0 github.com/xanzy/go-gitlab v0.37.0 go.jolheiser.com/beaver v1.0.2 + go.jolheiser.com/overlay v0.0.2 // indirect golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a // indirect golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43 golang.org/x/sys v0.0.0-20200909081042-eff7692f9009 // indirect diff --git a/go.sum b/go.sum index 8a0ffdb..6acbc9e 100644 --- a/go.sum +++ b/go.sum @@ -30,10 +30,9 @@ cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0Zeo cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= -code.gitea.io/sdk/gitea v0.12.2 h1:NQI8b/CT9AEQjsxbVIZ6gsPUXv38moT5y1ocN7n1YcQ= -code.gitea.io/sdk/gitea v0.12.2/go.mod h1:z3uwDV/b9Ls47NGukYM9XhnHtqPh/J+t40lsUrR6JDY= +code.gitea.io/sdk/gitea v0.13.2 h1:wAnT/J7Z62q3fJXbgnecoaOBh8CM1Qq0/DakWxiv4yA= +code.gitea.io/sdk/gitea v0.13.2/go.mod h1:lee2y8LeV3kQb2iK+hHlMqoadL4bp27QOkOV/hawLKg= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= -github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= @@ -42,7 +41,6 @@ github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5P github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= 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/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d h1:U+s90UTSYgptZMwQh2aRr3LuazLJIa+Pg3Kc1ylSYVY= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.0 h1:EoUDS0afbrsXAZ9YQ9jdu/mZ2sXgT1/2yyNng4PGlyM= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= @@ -115,19 +113,19 @@ github.com/hashicorp/go-hclog v0.9.2 h1:CG6TE5H9/JXsFWJCfoIVpKFIkFe6ysEuHirp4DxC 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/go-version v1.2.0 h1:3vNe/fWF5CBgRIguda1meWhsZHy3m8gCJ5wx+dIzX/E= -github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.2.1 h1:zEfKbn2+PDgroKdiOzqiE8rsmLqU2uwi5PB5pBJ3TkI= +github.com/hashicorp/go-version v1.2.1/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= 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= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/pelletier/go-toml v1.8.1 h1:1Nf83orprkJyknT6h7zbuEGUEjcyVlCxSUGTENmNCRM= +github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= @@ -149,12 +147,13 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= go.jolheiser.com/beaver v1.0.2 h1:KA2D6iO8MQhZi1nZYi/Chak/f1Cxfrs6b1XO623+Khk= go.jolheiser.com/beaver v1.0.2/go.mod h1:7X4F5+XOGSC3LejTShoBdqtRCnPWcnRgmYGmG3EKW8g= +go.jolheiser.com/overlay v0.0.2 h1:cwEHLbWqdH7lEOG87WUwgUGVqfOWBsWe03FiHHmuTWE= +go.jolheiser.com/overlay v0.0.2/go.mod h1:xNbssakJ3HjK4RnjuP38q9yQNS4wxXKsyprYIWWr2bg= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= @@ -198,7 +197,6 @@ golang.org/x/net v0.0.0-20181108082009-03003ca0c849/go.mod h1:mL1N/T3taQHkDXs73r 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= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3 h1:0GoQqolDA55aaLxZyTzK/Y2ePZzZTUrRacwib7cNsYQ= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -238,7 +236,6 @@ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv3hCI0z56oJR5vAMgBU= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -247,7 +244,6 @@ golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a h1:aYOabOQFp6Vj6W1F80affTUvO9UxmJRx8K0gsfABByQ= golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -268,7 +264,6 @@ golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200909081042-eff7692f9009 h1:W0lCpv29Hv0UaM1LXb9QlBHLNP8UFfcKjblhVCWftOM= golang.org/x/sys v0.0.0-20200909081042-eff7692f9009/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= @@ -400,7 +395,6 @@ google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGj google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= diff --git a/main.go b/main.go index 85cce38..9562d94 100644 --- a/main.go +++ b/main.go @@ -36,7 +36,11 @@ func main() { } func doAction(ctx *cli.Context) error { - if err := http.ListenAndServe(fmt.Sprintf(":%s", ctx.String("port")), router.Init()); err != nil { + mux, err := router.Init() + if err != nil { + return err + } + if err := http.ListenAndServe(fmt.Sprintf(":%s", ctx.String("port")), mux); err != nil { return err } return nil diff --git a/router/cache.go b/router/cache.go index c5a4c68..bc3b197 100644 --- a/router/cache.go +++ b/router/cache.go @@ -1,6 +1,10 @@ package router import ( + "go.jolheiser.com/beaver" + "go.jolheiser.com/vanity/flags" + "go.jolheiser.com/vanity/service" + "strings" "sync" "go.jolheiser.com/vanity/api" @@ -30,3 +34,54 @@ func (c *packageCache) Names() []string { } return names } + +func updateCache() { + packages, err := svc.Packages() + if err != nil { + beaver.Errorf("could not update packages: %v", err) + return + } + + // Filter + for name, pkg := range packages { + if err := service.Check(pkg); err != nil { + beaver.Debug(err) + delete(packages, name) + continue + } + goMod, err := svc.GoMod(pkg) + if err != nil { + beaver.Debugf("No go.mod could be found in the root directory of %s", pkg.Name) + delete(packages, name) + continue + } + lines := strings.Split(goMod, "\n") + line := strings.Fields(lines[0]) + if !strings.HasPrefix(line[1], flags.Domain) { + beaver.Debugf("%s is a Go project, however its module does not include this domain", pkg.Name) + delete(packages, name) + continue + } + beaver.Debugf("Including %s", pkg.Name) + } + + // Overrides + for name, pkg := range packages { + for key, override := range flags.Override { + if strings.EqualFold(name, key) { + beaver.Debugf("Overriding %s -> %s", name, override) + delete(packages, key) + pkg.Name = override + packages[override] = pkg + } + } + } + + // Add packages manually added to config + for _, pkg := range flags.ConfigPackages { + packages[pkg.Name] = pkg + } + + cache.Update(packages) + canUpdate = false +} diff --git a/router/cron.go b/router/cron.go index af6b21d..da3f126 100644 --- a/router/cron.go +++ b/router/cron.go @@ -1,73 +1,28 @@ package router import ( - "strings" + "go.jolheiser.com/beaver" + "go.jolheiser.com/vanity/service" "time" "go.jolheiser.com/vanity/flags" - "go.jolheiser.com/vanity/service" - - "go.jolheiser.com/beaver" ) -var svc service.Service +var ( + svc service.Service + canUpdate bool +) func cronStart() { + canUpdate = true ticker := time.NewTicker(flags.Interval) for { <-ticker.C - beaver.Debug("Running package update...") - cronUpdate() - beaver.Debugf("Finished package update: %s", cache.Names()) + if !flags.Manual && canUpdate { + beaver.Debug("Running package update...") + updateCache() + beaver.Debugf("Finished package update: %s", cache.Names()) + } + canUpdate = true } } - -func cronUpdate() { - packages, err := svc.Packages() - if err != nil { - beaver.Errorf("could not update packages: %v", err) - return - } - - // Filter - for name, pkg := range packages { - if err := service.Check(pkg); err != nil { - beaver.Debug(err) - delete(packages, name) - continue - } - goMod, err := svc.GoMod(pkg) - if err != nil { - beaver.Debugf("No go.mod could be found in the root directory of %s", pkg.Name) - delete(packages, name) - continue - } - lines := strings.Split(goMod, "\n") - line := strings.Fields(lines[0]) - if !strings.HasPrefix(line[1], flags.Domain) { - beaver.Debugf("%s is a Go project, however its module does not include this domain", pkg.Name) - delete(packages, name) - continue - } - beaver.Debugf("Including %s", pkg.Name) - } - - // Overrides - for name, pkg := range packages { - for key, override := range flags.Override { - if strings.EqualFold(name, key) { - beaver.Debugf("Overriding %s -> %s", name, override) - delete(packages, key) - pkg.Name = override - packages[override] = pkg - } - } - } - - // Add packages manually added to config - for _, pkg := range flags.ConfigPackages { - packages[pkg.Name] = pkg - } - - cache.Update(packages) -} diff --git a/router/router.go b/router/router.go index 2a77243..716e65b 100644 --- a/router/router.go +++ b/router/router.go @@ -1,16 +1,14 @@ package router import ( + "encoding/json" "fmt" "html/template" "net/http" - "runtime" "strings" "time" - "go.jolheiser.com/vanity/api" "go.jolheiser.com/vanity/flags" - "go.jolheiser.com/vanity/router/templates" "go.jolheiser.com/vanity/service" "github.com/go-chi/chi" @@ -18,38 +16,41 @@ import ( "go.jolheiser.com/beaver" ) -var ( - index = template.Must(template.New("index").Parse(templates.Head + templates.Index + templates.Foot)) - vanity = template.Must(template.New("vanity").Parse(templates.Head + templates.Vanity + templates.Foot)) -) +var tmpl *template.Template + +func Init() (*chi.Mux, error) { + var err error + tmpl, err = Templates() + if err != nil { + return nil, err + } -func Init() *chi.Mux { r := chi.NewRouter() r.Use(middleware.RedirectSlashes) r.Use(middleware.Recoverer) r.Use(middleware.Timeout(30 * time.Second)) r.Get("/", doIndex) + r.Head("/", doUpdate) r.Get("/*", doVanity) svc = service.New() beaver.Info("Warming up cache...") - cronUpdate() + updateCache() beaver.Infof("Finished warming up cache: %s", cache.Names()) go cronStart() beaver.Infof("Running vanity server at http://localhost:%d", flags.Port) - return r + return r, nil } func doIndex(res http.ResponseWriter, _ *http.Request) { - if err := index.Execute(res, map[string]interface{}{ + if err := tmpl.Lookup("index.tmpl").Execute(res, map[string]interface{}{ "Packages": cache.packages, - "AppVer": api.Version, - "GoVer": runtime.Version(), + "Index": true, }); err != nil { - beaver.Error(err) + beaver.Errorf("could not write response: %v", err) } } @@ -61,13 +62,33 @@ func doVanity(res http.ResponseWriter, req *http.Request) { return } - if err := vanity.Execute(res, map[string]interface{}{ + if err := tmpl.Lookup("vanity.tmpl").Execute(res, map[string]interface{}{ "Package": pkg, "Module": pkg.Module(flags.Domain), - "AppVer": api.Version, - "GoVer": runtime.Version(), "GoSource": fmt.Sprintf("%s %s %s %s", pkg.Module(flags.Domain), pkg.CloneHTTP, svc.GoDir(pkg), svc.GoFile(pkg)), + "Index": false, }); err != nil { - beaver.Error(err) + beaver.Errorf("could not write response: %v", err) + } +} + +func doUpdate(res http.ResponseWriter, _ *http.Request) { + res.Header().Set("Content-Type", "application/json") + + resp := map[string]bool{ + "updated": false, + } + if canUpdate { + updateCache() + resp["updated"] = true + } + + payload, err := json.Marshal(resp) + if err != nil { + beaver.Errorf("could not marshal payload: %v", err) + } + + if _, err = res.Write(payload); err != nil { + beaver.Errorf("could not write response: %v", err) } } diff --git a/router/templates.go b/router/templates.go new file mode 100644 index 0000000..5bd899d --- /dev/null +++ b/router/templates.go @@ -0,0 +1,44 @@ +package router + +import ( + "embed" + "go.jolheiser.com/overlay" + "go.jolheiser.com/vanity/api" + "html/template" + "os" + "path/filepath" + "runtime" +) + +//go:embed templates +var templates embed.FS + +func Templates() (*template.Template, error) { + bin, err := os.Executable() + if err != nil { + return nil, err + } + customPath := os.Getenv("VANITY_CUSTOM") + if customPath == "" { + customPath = filepath.Join(bin, "custom") + } + + ofs, err := overlay.New(customPath, templates) + if err != nil { + return nil, err + } + + return template.New("vanity").Funcs(funcMap).ParseFS(ofs, "templates/*") +} + +var funcMap = template.FuncMap{ + "AppVer": func() string { + return api.Version + }, + "GoVer": func() string { + return runtime.Version() + }, + "CanUpdate": func() bool { + return canUpdate + }, +} diff --git a/router/templates/foot.go b/router/templates/foot.go deleted file mode 100644 index 82e0492..0000000 --- a/router/templates/foot.go +++ /dev/null @@ -1,7 +0,0 @@ -package templates - -var Foot = ` -Version: {{.AppVer}} | {{.GoVer}} - - -` diff --git a/router/templates/foot.tmpl b/router/templates/foot.tmpl new file mode 100644 index 0000000..001d618 --- /dev/null +++ b/router/templates/foot.tmpl @@ -0,0 +1,25 @@ +
+ +

+Vanity Version: +{{AppVer}} +

+Go Version: +{{GoVer}} + + + + diff --git a/router/templates/head.go b/router/templates/head.go deleted file mode 100644 index 9fb8c57..0000000 --- a/router/templates/head.go +++ /dev/null @@ -1,23 +0,0 @@ -package templates - -var Head = ` - - - - - {{if .Package}} - - - - - - - - - - - {{end}} - Vanity - {{if .Package}}{{.Package.Name}}{{else}}Index{{end}} - - -` diff --git a/router/templates/head.tmpl b/router/templates/head.tmpl new file mode 100644 index 0000000..00435a2 --- /dev/null +++ b/router/templates/head.tmpl @@ -0,0 +1,21 @@ + + + + + {{if .Package}} + + + + + + + + + + + {{end}} + Vanity - {{if .Package}}{{.Package.Name}}{{else}}Index{{end}} + + +

Index

+
\ No newline at end of file diff --git a/router/templates/index.go b/router/templates/index.go deleted file mode 100644 index 7e6845e..0000000 --- a/router/templates/index.go +++ /dev/null @@ -1,12 +0,0 @@ -package templates - -var Index = ` -

Index

-
-

Imports:

- -` diff --git a/router/templates/index.tmpl b/router/templates/index.tmpl new file mode 100644 index 0000000..81fa411 --- /dev/null +++ b/router/templates/index.tmpl @@ -0,0 +1,8 @@ +{{template "head.tmpl" .}} +

Imports:

+ +{{template "foot.tmpl" .}} \ No newline at end of file diff --git a/router/templates/vanity.go b/router/templates/vanity.go deleted file mode 100644 index 8a76d19..0000000 --- a/router/templates/vanity.go +++ /dev/null @@ -1,10 +0,0 @@ -package templates - -var Vanity = ` -

Index

-
-

Name: {{.Package.Name}}

-

Source: {{.Package.WebURL}}

-{{if .Package.Description}}

Description: {{.Package.Description}}

{{end}} -

Documentation: https://pkg.go.dev/{{.Module}}

-` diff --git a/router/templates/vanity.tmpl b/router/templates/vanity.tmpl new file mode 100644 index 0000000..e36b63c --- /dev/null +++ b/router/templates/vanity.tmpl @@ -0,0 +1,20 @@ +{{template "head.tmpl" .}} +

+ Name: + {{.Package.Name}} +

+

+ Source: + {{.Package.WebURL}} +

+ {{if .Package.Description}} +

+ Description: + {{.Package.Description}} +

+ {{end}} +

+ Documentation: + https://pkg.go.dev/{{.Module}} +

+{{template "foot.tmpl" .}} \ No newline at end of file diff --git a/service/gitea.go b/service/gitea.go index 49017cb..a1a0a16 100644 --- a/service/gitea.go +++ b/service/gitea.go @@ -7,12 +7,16 @@ import ( "go.jolheiser.com/vanity/flags" "code.gitea.io/sdk/gitea" + "go.jolheiser.com/beaver" ) var _ Service = &Gitea{} func NewGitea() *Gitea { - client := gitea.NewClient(flags.BaseURL.String(), flags.Token) + client, err := gitea.NewClient(flags.BaseURL.String(), gitea.SetToken(flags.Token)) + if err != nil { + beaver.Errorf("could not create Gitea client: %v", err) + } return &Gitea{ client: client, } @@ -33,7 +37,7 @@ func (g Gitea) Packages() (map[string]*api.Package, error) { }, } - repos, err := g.client.ListUserRepos(flags.Namespace, opts) + repos, _, err := g.client.ListUserRepos(flags.Namespace, opts) if err != nil { return nil, err } @@ -71,6 +75,6 @@ func (g Gitea) GoFile(pkg *api.Package) string { } func (g Gitea) GoMod(pkg *api.Package) (string, error) { - content, err := g.client.GetFile(flags.Namespace, pkg.Name, pkg.Branch, "go.mod") + content, _, err := g.client.GetFile(flags.Namespace, pkg.Name, pkg.Branch, "go.mod") return string(content), err }