Move to github.com/tkw1536/pkglib package
This commit removes various modules that can be migrated to the github.com/tkw1536/pkglib package without any code changes (beyond module renamings).
This commit is contained in:
parent
30c25b8e2a
commit
c3ca8e2974
65 changed files with 103 additions and 1254 deletions
|
|
@ -8,8 +8,8 @@ import (
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/cli"
|
"github.com/FAU-CDI/wisski-distillery/internal/cli"
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/wisski"
|
"github.com/FAU-CDI/wisski-distillery/internal/wisski"
|
||||||
"github.com/tkw1536/goprogram/exit"
|
"github.com/tkw1536/goprogram/exit"
|
||||||
"github.com/tkw1536/goprogram/lib/collection"
|
|
||||||
"github.com/tkw1536/goprogram/status"
|
"github.com/tkw1536/goprogram/status"
|
||||||
|
"github.com/tkw1536/pkglib/collection"
|
||||||
)
|
)
|
||||||
|
|
||||||
// BlindUpdate is the 'blind_update' command
|
// BlindUpdate is the 'blind_update' command
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ import (
|
||||||
|
|
||||||
wisski_distillery "github.com/FAU-CDI/wisski-distillery"
|
wisski_distillery "github.com/FAU-CDI/wisski-distillery"
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/cli"
|
"github.com/FAU-CDI/wisski-distillery/internal/cli"
|
||||||
"github.com/tkw1536/goprogram/lib/collection"
|
"github.com/tkw1536/pkglib/collection"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Info is then 'info' command
|
// Info is then 'info' command
|
||||||
|
|
|
||||||
26
go.mod
26
go.mod
|
|
@ -4,11 +4,9 @@ go 1.18
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/FAU-CDI/wdresolve v0.0.0-20230108072141-c9c6779d7c41
|
github.com/FAU-CDI/wdresolve v0.0.0-20230108072141-c9c6779d7c41
|
||||||
github.com/Showmax/go-fqdn v1.0.0
|
|
||||||
github.com/alessio/shellescape v1.4.1
|
github.com/alessio/shellescape v1.4.1
|
||||||
github.com/feiin/sqlstring v0.3.0
|
|
||||||
github.com/gliderlabs/ssh v0.3.5
|
github.com/gliderlabs/ssh v0.3.5
|
||||||
github.com/go-sql-driver/mysql v1.6.0
|
github.com/go-sql-driver/mysql v1.7.0
|
||||||
github.com/gorilla/csrf v1.7.1
|
github.com/gorilla/csrf v1.7.1
|
||||||
github.com/gorilla/sessions v1.2.1
|
github.com/gorilla/sessions v1.2.1
|
||||||
github.com/gorilla/websocket v1.5.0
|
github.com/gorilla/websocket v1.5.0
|
||||||
|
|
@ -17,32 +15,32 @@ require (
|
||||||
github.com/pquerna/otp v1.4.0
|
github.com/pquerna/otp v1.4.0
|
||||||
github.com/rs/zerolog v1.29.0
|
github.com/rs/zerolog v1.29.0
|
||||||
github.com/tdewolff/minify v2.3.6+incompatible
|
github.com/tdewolff/minify v2.3.6+incompatible
|
||||||
github.com/tkw1536/goprogram v0.2.4
|
github.com/tkw1536/goprogram v0.3.0
|
||||||
github.com/tkw1536/pkglib v0.0.0-20230225192547-93a1aa42a292
|
github.com/tkw1536/pkglib v0.0.0-20230225192547-93a1aa42a292
|
||||||
github.com/yuin/goldmark v1.4.13
|
github.com/yuin/goldmark v1.5.4
|
||||||
github.com/yuin/goldmark-meta v1.1.0
|
github.com/yuin/goldmark-meta v1.1.0
|
||||||
golang.org/x/crypto v0.3.0
|
golang.org/x/crypto v0.6.0
|
||||||
golang.org/x/exp v0.0.0-20230213192124-5e25df0256eb
|
golang.org/x/exp v0.0.0-20230224173230-c95f2b4c22f2
|
||||||
golang.org/x/sync v0.1.0
|
golang.org/x/sync v0.1.0
|
||||||
golang.org/x/term v0.5.0
|
golang.org/x/term v0.5.0
|
||||||
gopkg.in/yaml.v3 v3.0.1
|
gopkg.in/yaml.v3 v3.0.1
|
||||||
gorm.io/driver/mysql v1.4.4
|
gorm.io/driver/mysql v1.4.7
|
||||||
gorm.io/gorm v1.24.2
|
gorm.io/gorm v1.24.5
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
github.com/Showmax/go-fqdn v1.0.0 // indirect
|
||||||
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be // indirect
|
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be // indirect
|
||||||
github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc // indirect
|
github.com/boombuler/barcode v1.0.1 // indirect
|
||||||
|
github.com/feiin/sqlstring v0.3.0 // indirect
|
||||||
github.com/gorilla/securecookie v1.1.1 // indirect
|
github.com/gorilla/securecookie v1.1.1 // indirect
|
||||||
github.com/gosuri/uilive v0.0.4 // indirect
|
github.com/gosuri/uilive v0.0.4 // indirect
|
||||||
github.com/jessevdk/go-flags v1.5.0 // indirect
|
github.com/jessevdk/go-flags v1.5.0 // indirect
|
||||||
github.com/jinzhu/inflection v1.0.0 // indirect
|
github.com/jinzhu/inflection v1.0.0 // indirect
|
||||||
github.com/jinzhu/now v1.1.5 // indirect
|
github.com/jinzhu/now v1.1.5 // indirect
|
||||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||||
github.com/mattn/go-isatty v0.0.16 // indirect
|
github.com/mattn/go-isatty v0.0.17 // indirect
|
||||||
github.com/tdewolff/parse v2.3.4+incompatible // indirect
|
github.com/tdewolff/parse v2.3.4+incompatible // indirect
|
||||||
github.com/tdewolff/test v1.0.7 // indirect
|
|
||||||
golang.org/x/sys v0.5.0 // indirect
|
golang.org/x/sys v0.5.0 // indirect
|
||||||
golang.org/x/tools v0.4.0 // indirect
|
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||||
gopkg.in/yaml.v2 v2.3.0 // indirect
|
|
||||||
)
|
)
|
||||||
|
|
|
||||||
49
go.sum
49
go.sum
|
|
@ -6,8 +6,9 @@ github.com/alessio/shellescape v1.4.1 h1:V7yhSDDn8LP4lc4jS8pFkt0zCnzVJlG5JXy9BVK
|
||||||
github.com/alessio/shellescape v1.4.1/go.mod h1:PZAiSCk0LJaZkiCSkPv8qIobYglO3FPpyFjDCtHLS30=
|
github.com/alessio/shellescape v1.4.1/go.mod h1:PZAiSCk0LJaZkiCSkPv8qIobYglO3FPpyFjDCtHLS30=
|
||||||
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8=
|
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8=
|
||||||
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4=
|
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4=
|
||||||
github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc h1:biVzkmvwrH8WK8raXaxBx6fRVTlJILwEwQGL1I/ByEI=
|
|
||||||
github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=
|
github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=
|
||||||
|
github.com/boombuler/barcode v1.0.1 h1:NDBbPmhS+EqABEs5Kg3n/5ZNjy73Pz7SIV+KCeqyXcs=
|
||||||
|
github.com/boombuler/barcode v1.0.1/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=
|
||||||
github.com/coreos/go-systemd/v22 v22.3.3-0.20220203105225-a9a7ef127534/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
github.com/coreos/go-systemd/v22 v22.3.3-0.20220203105225-a9a7ef127534/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
||||||
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
|
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
|
@ -15,8 +16,8 @@ github.com/feiin/sqlstring v0.3.0 h1:iyPEFijI2BxpY2M+AuhIvdNManzXa2OwGzuPaEMLUgo
|
||||||
github.com/feiin/sqlstring v0.3.0/go.mod h1:xpZTjVUw1nD3hMgF9SMRdPiooKSikLf4PS5j2NTn3RI=
|
github.com/feiin/sqlstring v0.3.0/go.mod h1:xpZTjVUw1nD3hMgF9SMRdPiooKSikLf4PS5j2NTn3RI=
|
||||||
github.com/gliderlabs/ssh v0.3.5 h1:OcaySEmAQJgyYcArR+gGGTHCyE7nvhEMTlYY+Dp8CpY=
|
github.com/gliderlabs/ssh v0.3.5 h1:OcaySEmAQJgyYcArR+gGGTHCyE7nvhEMTlYY+Dp8CpY=
|
||||||
github.com/gliderlabs/ssh v0.3.5/go.mod h1:8XB4KraRrX39qHhT6yxPsHedjA08I/uBVwj4xC+/+z4=
|
github.com/gliderlabs/ssh v0.3.5/go.mod h1:8XB4KraRrX39qHhT6yxPsHedjA08I/uBVwj4xC+/+z4=
|
||||||
github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE=
|
github.com/go-sql-driver/mysql v1.7.0 h1:ueSltNNllEqE3qcWBTD0iQd3IpL/6U+mJxLkazJ7YPc=
|
||||||
github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
|
||||||
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||||
github.com/gorilla/csrf v1.7.1 h1:Ir3o2c1/Uzj6FBxMlAUB6SivgVMy1ONXwYgXn+/aHPE=
|
github.com/gorilla/csrf v1.7.1 h1:Ir3o2c1/Uzj6FBxMlAUB6SivgVMy1ONXwYgXn+/aHPE=
|
||||||
github.com/gorilla/csrf v1.7.1/go.mod h1:+a/4tCmqhG6/w4oafeAZ9pEa3/NZOWYVbD9fV0FwIQA=
|
github.com/gorilla/csrf v1.7.1/go.mod h1:+a/4tCmqhG6/w4oafeAZ9pEa3/NZOWYVbD9fV0FwIQA=
|
||||||
|
|
@ -41,8 +42,9 @@ github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb
|
||||||
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
||||||
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
||||||
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
|
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
|
||||||
github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ=
|
|
||||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||||
|
github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng=
|
||||||
|
github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
|
|
@ -50,8 +52,6 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN
|
||||||
github.com/pquerna/otp v1.4.0 h1:wZvl1TIVxKRThZIBiwOOHOGP/1+nZyWBil9Y2XNEDzg=
|
github.com/pquerna/otp v1.4.0 h1:wZvl1TIVxKRThZIBiwOOHOGP/1+nZyWBil9Y2XNEDzg=
|
||||||
github.com/pquerna/otp v1.4.0/go.mod h1:dkJfzwRKNiegxyNb54X/3fLwhCynbMspSyWKnvi1AEg=
|
github.com/pquerna/otp v1.4.0/go.mod h1:dkJfzwRKNiegxyNb54X/3fLwhCynbMspSyWKnvi1AEg=
|
||||||
github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
|
github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
|
||||||
github.com/rs/zerolog v1.28.0 h1:MirSo27VyNi7RJYP3078AA1+Cyzd2GB66qy3aUHvsWY=
|
|
||||||
github.com/rs/zerolog v1.28.0/go.mod h1:NILgTygv/Uej1ra5XxGf82ZFSLk58MFGAUS2o6usyD0=
|
|
||||||
github.com/rs/zerolog v1.29.0 h1:Zes4hju04hjbvkVkOhdl2HpZa+0PmVwigmo8XoORE5w=
|
github.com/rs/zerolog v1.29.0 h1:Zes4hju04hjbvkVkOhdl2HpZa+0PmVwigmo8XoORE5w=
|
||||||
github.com/rs/zerolog v1.29.0/go.mod h1:NILgTygv/Uej1ra5XxGf82ZFSLk58MFGAUS2o6usyD0=
|
github.com/rs/zerolog v1.29.0/go.mod h1:NILgTygv/Uej1ra5XxGf82ZFSLk58MFGAUS2o6usyD0=
|
||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
|
|
@ -62,22 +62,19 @@ github.com/tdewolff/minify v2.3.6+incompatible/go.mod h1:9Ov578KJUmAWpS6NeZwRZyT
|
||||||
github.com/tdewolff/parse v2.3.4+incompatible h1:x05/cnGwIMf4ceLuDMBOdQ1qGniMoxpP46ghf0Qzh38=
|
github.com/tdewolff/parse v2.3.4+incompatible h1:x05/cnGwIMf4ceLuDMBOdQ1qGniMoxpP46ghf0Qzh38=
|
||||||
github.com/tdewolff/parse v2.3.4+incompatible/go.mod h1:8oBwCsVmUkgHO8M5iCzSIDtpzXOT0WXX9cWhz+bIzJQ=
|
github.com/tdewolff/parse v2.3.4+incompatible/go.mod h1:8oBwCsVmUkgHO8M5iCzSIDtpzXOT0WXX9cWhz+bIzJQ=
|
||||||
github.com/tdewolff/test v1.0.7 h1:8Vs0142DmPFW/bQeHRP3MV19m1gvndjUb1sn8yy74LM=
|
github.com/tdewolff/test v1.0.7 h1:8Vs0142DmPFW/bQeHRP3MV19m1gvndjUb1sn8yy74LM=
|
||||||
github.com/tdewolff/test v1.0.7/go.mod h1:6DAvZliBAAnD7rhVgwaM7DE5/d9NMOAJ09SqYqeK4QE=
|
github.com/tkw1536/goprogram v0.3.0 h1:bMnr+PMZHRaaw3atIHz2I0/vCdwl2Bx8KaNutTD7psg=
|
||||||
github.com/tkw1536/goprogram v0.2.4 h1:1l3+j8xjY3E3uf+ba3QRGWm09ucFCKrnNLq6g1Gq8YA=
|
github.com/tkw1536/goprogram v0.3.0/go.mod h1:lIWTpzLCbji7b9mSU+iPrQYTJOa0DgOE5is8UyW9/n0=
|
||||||
github.com/tkw1536/goprogram v0.2.4/go.mod h1:3Ngcwy7jtsZ+pINc+JfLdf8TWbvthdSS2T6Vbg44Fy8=
|
|
||||||
github.com/tkw1536/pkglib v0.0.0-20230225192547-93a1aa42a292 h1:/OeSU0bywyN9C4AJ9TARXUKxCZFK0lkZUp0MoHXCa2k=
|
github.com/tkw1536/pkglib v0.0.0-20230225192547-93a1aa42a292 h1:/OeSU0bywyN9C4AJ9TARXUKxCZFK0lkZUp0MoHXCa2k=
|
||||||
github.com/tkw1536/pkglib v0.0.0-20230225192547-93a1aa42a292/go.mod h1:R+8tKMAkSXC1+XGzxNUKx2DnPJqObycYeo4PKjWYkMg=
|
github.com/tkw1536/pkglib v0.0.0-20230225192547-93a1aa42a292/go.mod h1:R+8tKMAkSXC1+XGzxNUKx2DnPJqObycYeo4PKjWYkMg=
|
||||||
github.com/yuin/goldmark v1.4.13 h1:fVcFKWvrslecOb/tg+Cc05dkeYx540o0FuFt3nUVDoE=
|
github.com/yuin/goldmark v1.5.4 h1:2uY/xC0roWy8IBEGLgB1ywIoEJFGmRrX21YQcvGZzjU=
|
||||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
github.com/yuin/goldmark v1.5.4/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||||
github.com/yuin/goldmark-meta v1.1.0 h1:pWw+JLHGZe8Rk0EGsMVssiNb/AaPMHfSRszZeUeiOUc=
|
github.com/yuin/goldmark-meta v1.1.0 h1:pWw+JLHGZe8Rk0EGsMVssiNb/AaPMHfSRszZeUeiOUc=
|
||||||
github.com/yuin/goldmark-meta v1.1.0/go.mod h1:U4spWENafuA7Zyg+Lj5RqK/MF+ovMYtBvXi1lBb2VP0=
|
github.com/yuin/goldmark-meta v1.1.0/go.mod h1:U4spWENafuA7Zyg+Lj5RqK/MF+ovMYtBvXi1lBb2VP0=
|
||||||
golang.org/x/crypto v0.0.0-20220826181053-bd7e27e6170d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
golang.org/x/crypto v0.0.0-20220826181053-bd7e27e6170d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||||
golang.org/x/crypto v0.3.0 h1:a06MkbcxBrEFc0w0QIZWXrH/9cCX6KJyWbBOIwAn+7A=
|
golang.org/x/crypto v0.6.0 h1:qfktjS5LUO+fFKeJXZ+ikTRijMmljikvG68fpMMruSc=
|
||||||
golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
|
golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58=
|
||||||
golang.org/x/exp v0.0.0-20230105202349-8879d0199aa3 h1:fJwx88sMf5RXwDwziL0/Mn9Wqs+efMSo/RYcL+37W9c=
|
golang.org/x/exp v0.0.0-20230224173230-c95f2b4c22f2 h1:Jvc7gsqn21cJHCmAWx0LiimpP18LZmUxkT5Mp7EZ1mI=
|
||||||
golang.org/x/exp v0.0.0-20230105202349-8879d0199aa3/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc=
|
golang.org/x/exp v0.0.0-20230224173230-c95f2b4c22f2/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc=
|
||||||
golang.org/x/exp v0.0.0-20230213192124-5e25df0256eb h1:PaBZQdo+iSDyHT053FjUCgZQ/9uqVwPOcl7KSWhKn6w=
|
|
||||||
golang.org/x/exp v0.0.0-20230213192124-5e25df0256eb/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc=
|
|
||||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||||
golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
|
golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
|
||||||
golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
|
golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
|
||||||
|
|
@ -91,30 +88,24 @@ golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||||
golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220825204002-c680a09ffe64/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220825204002-c680a09ffe64/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.3.0 h1:w8ZOecv6NaNa/zC8944JTU3vz4u6Lagfk4RPQxv92NQ=
|
|
||||||
golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
||||||
golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU=
|
golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU=
|
||||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||||
golang.org/x/term v0.0.0-20220722155259-a9ba230a4035/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
golang.org/x/term v0.0.0-20220722155259-a9ba230a4035/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||||
golang.org/x/term v0.3.0 h1:qoo4akIqOcDME5bhc/NgxUdovd6BSS2uMsVjB56q1xI=
|
|
||||||
golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA=
|
|
||||||
golang.org/x/term v0.5.0 h1:n2a8QNdAb0sZNpU9R1ALUXBbY+w51fCQDN+7EdxNBsY=
|
golang.org/x/term v0.5.0 h1:n2a8QNdAb0sZNpU9R1ALUXBbY+w51fCQDN+7EdxNBsY=
|
||||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
golang.org/x/tools v0.4.0 h1:7mTAgkunk3fr4GAloyyCasadO6h9zSsQZbwvcaIciV4=
|
|
||||||
golang.org/x/tools v0.4.0/go.mod h1:UE5sM2OK9E/d67R0ANs2xJizIymRP5gJU295PvKXxjQ=
|
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
|
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||||
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
gorm.io/driver/mysql v1.4.4 h1:MX0K9Qvy0Na4o7qSC/YI7XxqUw5KDw01umqgID+svdQ=
|
gorm.io/driver/mysql v1.4.7 h1:rY46lkCspzGHn7+IYsNpSfEv9tA+SU4SkkB+GFX125Y=
|
||||||
gorm.io/driver/mysql v1.4.4/go.mod h1:BCg8cKI+R0j/rZRQxeKis/forqRwRSYOR8OM3Wo6hOM=
|
gorm.io/driver/mysql v1.4.7/go.mod h1:SxzItlnT1cb6e1e4ZRpgJN2VYtcqJgqnHxWr4wsP8oc=
|
||||||
gorm.io/gorm v1.23.8/go.mod h1:l2lP/RyAtc1ynaTjFksBde/O8v9oOGIApu2/xRitmZk=
|
gorm.io/gorm v1.23.8/go.mod h1:l2lP/RyAtc1ynaTjFksBde/O8v9oOGIApu2/xRitmZk=
|
||||||
gorm.io/gorm v1.24.2 h1:9wR6CFD+G8nOusLdvkZelOEhpJVwwHzpQOUM+REd6U0=
|
gorm.io/gorm v1.24.5 h1:g6OPREKqqlWq4kh/3MCQbZKImeB9e6Xgc4zD+JgNZGE=
|
||||||
gorm.io/gorm v1.24.2/go.mod h1:DVrVomtaYTbqs7gB/x2uVvqnXzv0nqjB396B8cG4dBA=
|
gorm.io/gorm v1.24.5/go.mod h1:DVrVomtaYTbqs7gB/x2uVvqnXzv0nqjB396B8cG4dBA=
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ import (
|
||||||
"reflect"
|
"reflect"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/FAU-CDI/wisski-distillery/pkg/pools"
|
"github.com/tkw1536/pkglib/pools"
|
||||||
"github.com/tkw1536/pkglib/yamlx"
|
"github.com/tkw1536/pkglib/yamlx"
|
||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/tkw1536/goprogram/lib/collection"
|
"github.com/tkw1536/pkglib/collection"
|
||||||
)
|
)
|
||||||
|
|
||||||
type HTTPConfig struct {
|
type HTTPConfig struct {
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ import (
|
||||||
|
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/config/validators"
|
"github.com/FAU-CDI/wisski-distillery/internal/config/validators"
|
||||||
"github.com/FAU-CDI/wisski-distillery/pkg/environment"
|
"github.com/FAU-CDI/wisski-distillery/pkg/environment"
|
||||||
"github.com/FAU-CDI/wisski-distillery/pkg/validator"
|
"github.com/tkw1536/pkglib/validator"
|
||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,8 +6,8 @@ import (
|
||||||
|
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/bootstrap"
|
"github.com/FAU-CDI/wisski-distillery/internal/bootstrap"
|
||||||
"github.com/FAU-CDI/wisski-distillery/pkg/environment"
|
"github.com/FAU-CDI/wisski-distillery/pkg/environment"
|
||||||
"github.com/FAU-CDI/wisski-distillery/pkg/hostname"
|
|
||||||
"github.com/FAU-CDI/wisski-distillery/pkg/password"
|
"github.com/FAU-CDI/wisski-distillery/pkg/password"
|
||||||
|
"github.com/tkw1536/pkglib/hostname"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Template is a template for the configuration file
|
// Template is a template for the configuration file
|
||||||
|
|
@ -31,7 +31,7 @@ func (tpl *Template) SetDefaults(env environment.Environment) (err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if tpl.DefaultDomain == "" {
|
if tpl.DefaultDomain == "" {
|
||||||
tpl.DefaultDomain = hostname.FQDN(env)
|
tpl.DefaultDomain = hostname.FQDN() // TODO: Make this environment specific
|
||||||
}
|
}
|
||||||
|
|
||||||
if tpl.SelfOverridesFile == "" {
|
if tpl.SelfOverridesFile == "" {
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ package validators
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/FAU-CDI/wisski-distillery/pkg/environment"
|
"github.com/FAU-CDI/wisski-distillery/pkg/environment"
|
||||||
"github.com/FAU-CDI/wisski-distillery/pkg/validator"
|
"github.com/tkw1536/pkglib/validator"
|
||||||
)
|
)
|
||||||
|
|
||||||
// New creates a new set of standard validators for the configuration
|
// New creates a new set of standard validators for the configuration
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ package dis
|
||||||
import (
|
import (
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/dis/component"
|
"github.com/FAU-CDI/wisski-distillery/internal/dis/component"
|
||||||
"github.com/FAU-CDI/wisski-distillery/pkg/lazy"
|
"github.com/FAU-CDI/wisski-distillery/pkg/lazy"
|
||||||
"github.com/tkw1536/goprogram/lib/collection"
|
"github.com/tkw1536/pkglib/collection"
|
||||||
)
|
)
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ import (
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/auth"
|
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/auth"
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/sql"
|
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/sql"
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/models"
|
"github.com/FAU-CDI/wisski-distillery/internal/models"
|
||||||
"github.com/tkw1536/goprogram/lib/reflectx"
|
"github.com/tkw1536/pkglib/reflectx"
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,11 +10,11 @@ import (
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/dis/component"
|
"github.com/FAU-CDI/wisski-distillery/internal/dis/component"
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/models"
|
"github.com/FAU-CDI/wisski-distillery/internal/models"
|
||||||
"github.com/FAU-CDI/wisski-distillery/pkg/password"
|
"github.com/FAU-CDI/wisski-distillery/pkg/password"
|
||||||
"github.com/FAU-CDI/wisski-distillery/pkg/pools"
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/pquerna/otp"
|
"github.com/pquerna/otp"
|
||||||
"github.com/pquerna/otp/totp"
|
"github.com/pquerna/otp/totp"
|
||||||
"github.com/tkw1536/goprogram/lib/reflectx"
|
"github.com/tkw1536/pkglib/pools"
|
||||||
|
"github.com/tkw1536/pkglib/reflectx"
|
||||||
"golang.org/x/crypto/bcrypt"
|
"golang.org/x/crypto/bcrypt"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,8 +8,8 @@ import (
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/models"
|
"github.com/FAU-CDI/wisski-distillery/internal/models"
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/status"
|
"github.com/FAU-CDI/wisski-distillery/internal/status"
|
||||||
"github.com/FAU-CDI/wisski-distillery/pkg/environment"
|
"github.com/FAU-CDI/wisski-distillery/pkg/environment"
|
||||||
"github.com/tkw1536/goprogram/lib/collection"
|
"github.com/tkw1536/pkglib/collection"
|
||||||
"github.com/tkw1536/goprogram/lib/reflectx"
|
"github.com/tkw1536/pkglib/reflectx"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Logger is responsible for logging backups and snapshots
|
// Logger is responsible for logging backups and snapshots
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,8 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
"github.com/FAU-CDI/wisski-distillery/pkg/countwriter"
|
"github.com/tkw1536/pkglib/pools"
|
||||||
"github.com/FAU-CDI/wisski-distillery/pkg/pools"
|
"github.com/tkw1536/pkglib/sequence"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (snapshot Snapshot) String() string {
|
func (snapshot Snapshot) String() string {
|
||||||
|
|
@ -19,7 +19,7 @@ func (snapshot Snapshot) String() string {
|
||||||
|
|
||||||
// Report writes a report from snapshot into w
|
// Report writes a report from snapshot into w
|
||||||
func (snapshot Snapshot) Report(w io.Writer) (int, error) {
|
func (snapshot Snapshot) Report(w io.Writer) (int, error) {
|
||||||
ww := countwriter.NewCountWriter(w)
|
ww := &sequence.Writer{Writer: w}
|
||||||
|
|
||||||
encoder := json.NewEncoder(ww)
|
encoder := json.NewEncoder(ww)
|
||||||
encoder.SetIndent("", " ")
|
encoder.SetIndent("", " ")
|
||||||
|
|
@ -74,7 +74,7 @@ func (backup Backup) String() string {
|
||||||
|
|
||||||
// Report formats a report for this backup, and writes it into Writer.
|
// Report formats a report for this backup, and writes it into Writer.
|
||||||
func (backup Backup) Report(w io.Writer) (int, error) {
|
func (backup Backup) Report(w io.Writer) (int, error) {
|
||||||
cw := countwriter.NewCountWriter(w)
|
cw := &sequence.Writer{Writer: w}
|
||||||
|
|
||||||
encoder := json.NewEncoder(cw)
|
encoder := json.NewEncoder(cw)
|
||||||
encoder.SetIndent("", " ")
|
encoder.SetIndent("", " ")
|
||||||
|
|
|
||||||
|
|
@ -12,8 +12,8 @@ import (
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/wisski"
|
"github.com/FAU-CDI/wisski-distillery/internal/wisski"
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/wisski/ingredient/locker"
|
"github.com/FAU-CDI/wisski-distillery/internal/wisski/ingredient/locker"
|
||||||
"github.com/FAU-CDI/wisski-distillery/pkg/logging"
|
"github.com/FAU-CDI/wisski-distillery/pkg/logging"
|
||||||
"github.com/tkw1536/goprogram/lib/collection"
|
|
||||||
"github.com/tkw1536/goprogram/status"
|
"github.com/tkw1536/goprogram/status"
|
||||||
|
"github.com/tkw1536/pkglib/collection"
|
||||||
"golang.org/x/exp/slices"
|
"golang.org/x/exp/slices"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ import (
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/dis/component"
|
"github.com/FAU-CDI/wisski-distillery/internal/dis/component"
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/sql"
|
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/sql"
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/models"
|
"github.com/FAU-CDI/wisski-distillery/internal/models"
|
||||||
"github.com/tkw1536/goprogram/lib/reflectx"
|
"github.com/tkw1536/pkglib/reflectx"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Component meta is responsible for managing metadata per WissKI Instance
|
// Component meta is responsible for managing metadata per WissKI Instance
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ import (
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/dis/component"
|
"github.com/FAU-CDI/wisski-distillery/internal/dis/component"
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/sql"
|
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/sql"
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/models"
|
"github.com/FAU-CDI/wisski-distillery/internal/models"
|
||||||
"github.com/tkw1536/goprogram/lib/collection"
|
"github.com/tkw1536/pkglib/collection"
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/FAU-CDI/wisski-distillery/pkg/mux"
|
"github.com/tkw1536/pkglib/mux"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Routeable is a component that is servable
|
// Routeable is a component that is servable
|
||||||
|
|
|
||||||
|
|
@ -10,8 +10,8 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/dis/component"
|
"github.com/FAU-CDI/wisski-distillery/internal/dis/component"
|
||||||
"github.com/FAU-CDI/wisski-distillery/pkg/timex"
|
|
||||||
"github.com/rs/zerolog"
|
"github.com/rs/zerolog"
|
||||||
|
"github.com/tkw1536/pkglib/timex"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Cron struct {
|
type Cron struct {
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ import (
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/server/templating"
|
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/server/templating"
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/status"
|
"github.com/FAU-CDI/wisski-distillery/internal/status"
|
||||||
"github.com/FAU-CDI/wisski-distillery/pkg/httpx"
|
"github.com/FAU-CDI/wisski-distillery/pkg/httpx"
|
||||||
"github.com/FAU-CDI/wisski-distillery/pkg/pools"
|
"github.com/tkw1536/pkglib/pools"
|
||||||
)
|
)
|
||||||
|
|
||||||
//go:embed "public.html"
|
//go:embed "public.html"
|
||||||
|
|
|
||||||
|
|
@ -12,8 +12,8 @@ import (
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/dis/component"
|
"github.com/FAU-CDI/wisski-distillery/internal/dis/component"
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/server/assets"
|
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/server/assets"
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/server/templating"
|
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/server/templating"
|
||||||
"github.com/FAU-CDI/wisski-distillery/pkg/pools"
|
|
||||||
"github.com/rs/zerolog"
|
"github.com/rs/zerolog"
|
||||||
|
"github.com/tkw1536/pkglib/pools"
|
||||||
"github.com/yuin/goldmark"
|
"github.com/yuin/goldmark"
|
||||||
gmmeta "github.com/yuin/goldmark-meta"
|
gmmeta "github.com/yuin/goldmark-meta"
|
||||||
"github.com/yuin/goldmark/parser"
|
"github.com/yuin/goldmark/parser"
|
||||||
|
|
|
||||||
|
|
@ -8,9 +8,10 @@ import (
|
||||||
|
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/dis/component"
|
"github.com/FAU-CDI/wisski-distillery/internal/dis/component"
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/server/templating"
|
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/server/templating"
|
||||||
"github.com/FAU-CDI/wisski-distillery/pkg/cancel"
|
"github.com/tkw1536/pkglib/contextx"
|
||||||
|
"github.com/tkw1536/pkglib/mux"
|
||||||
|
|
||||||
"github.com/FAU-CDI/wisski-distillery/pkg/httpx"
|
"github.com/FAU-CDI/wisski-distillery/pkg/httpx"
|
||||||
"github.com/FAU-CDI/wisski-distillery/pkg/mux"
|
|
||||||
"github.com/gorilla/csrf"
|
"github.com/gorilla/csrf"
|
||||||
"github.com/rs/zerolog"
|
"github.com/rs/zerolog"
|
||||||
)
|
)
|
||||||
|
|
@ -103,8 +104,8 @@ func (server *Server) Server(ctx context.Context, progress io.Writer) (public ht
|
||||||
}
|
}
|
||||||
|
|
||||||
// apply the given context function
|
// apply the given context function
|
||||||
public = httpx.WithContextWrapper(&publicM, func(rcontext context.Context) context.Context { return cancel.ValuesOf(rcontext, ctx) })
|
public = httpx.WithContextWrapper(&publicM, func(rcontext context.Context) context.Context { return contextx.WithValuesOf(rcontext, ctx) })
|
||||||
internal = httpx.WithContextWrapper(&internalM, func(rcontext context.Context) context.Context { return cancel.ValuesOf(rcontext, ctx) })
|
internal = httpx.WithContextWrapper(&internalM, func(rcontext context.Context) context.Context { return contextx.WithValuesOf(rcontext, ctx) })
|
||||||
err = nil
|
err = nil
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,10 +11,10 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/FAU-CDI/wisski-distillery/pkg/httpx"
|
"github.com/FAU-CDI/wisski-distillery/pkg/httpx"
|
||||||
"github.com/FAU-CDI/wisski-distillery/pkg/pools"
|
|
||||||
"github.com/FAU-CDI/wisski-distillery/pkg/timex"
|
|
||||||
"github.com/gorilla/csrf"
|
"github.com/gorilla/csrf"
|
||||||
"github.com/rs/zerolog"
|
"github.com/rs/zerolog"
|
||||||
|
"github.com/tkw1536/pkglib/pools"
|
||||||
|
"github.com/tkw1536/pkglib/timex"
|
||||||
)
|
)
|
||||||
|
|
||||||
//go:embed "src/base.html"
|
//go:embed "src/base.html"
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ import (
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/dis/component"
|
"github.com/FAU-CDI/wisski-distillery/internal/dis/component"
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/server/assets"
|
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/server/assets"
|
||||||
"github.com/rs/zerolog"
|
"github.com/rs/zerolog"
|
||||||
"github.com/tkw1536/goprogram/lib/reflectx"
|
"github.com/tkw1536/pkglib/reflectx"
|
||||||
"golang.org/x/exp/slices"
|
"golang.org/x/exp/slices"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/dis/component"
|
"github.com/FAU-CDI/wisski-distillery/internal/dis/component"
|
||||||
"github.com/FAU-CDI/wisski-distillery/pkg/mux"
|
"github.com/tkw1536/pkglib/mux"
|
||||||
"golang.org/x/exp/slices"
|
"golang.org/x/exp/slices"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ import (
|
||||||
"html/template"
|
"html/template"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
|
||||||
"github.com/tkw1536/goprogram/lib/reflectx"
|
"github.com/tkw1536/pkglib/reflectx"
|
||||||
"golang.org/x/exp/slices"
|
"golang.org/x/exp/slices"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ import (
|
||||||
|
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/dis/component"
|
"github.com/FAU-CDI/wisski-distillery/internal/dis/component"
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/models"
|
"github.com/FAU-CDI/wisski-distillery/internal/models"
|
||||||
"github.com/FAU-CDI/wisski-distillery/pkg/timex"
|
"github.com/tkw1536/pkglib/timex"
|
||||||
)
|
)
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,8 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
|
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/models"
|
"github.com/FAU-CDI/wisski-distillery/internal/models"
|
||||||
"github.com/FAU-CDI/wisski-distillery/pkg/errorx"
|
"github.com/tkw1536/pkglib/errorx"
|
||||||
"github.com/FAU-CDI/wisski-distillery/pkg/sqle"
|
"github.com/tkw1536/pkglib/sqlx"
|
||||||
)
|
)
|
||||||
|
|
||||||
var errProvisionInvalidDatabaseParams = errors.New("Provision: Invalid parameters")
|
var errProvisionInvalidDatabaseParams = errors.New("Provision: Invalid parameters")
|
||||||
|
|
@ -36,7 +36,7 @@ func (sql *SQL) CreateDatabase(ctx context.Context, name, user, password string)
|
||||||
// Apparently it's a "feature", see https://github.com/go-sql-driver/mysql/issues/398#issuecomment-169951763.
|
// Apparently it's a "feature", see https://github.com/go-sql-driver/mysql/issues/398#issuecomment-169951763.
|
||||||
|
|
||||||
// quick and dirty check to make sure that all the names won't sql inject.
|
// quick and dirty check to make sure that all the names won't sql inject.
|
||||||
if !sqle.IsSafeDatabaseLiteral(name) || !sqle.IsSafeDatabaseSingleQuote(user) || !sqle.IsSafeDatabaseSingleQuote(password) {
|
if !sqlx.IsSafeDatabaseLiteral(name) || !sqlx.IsSafeDatabaseSingleQuote(user) || !sqlx.IsSafeDatabaseSingleQuote(password) {
|
||||||
return errProvisionInvalidDatabaseParams
|
return errProvisionInvalidDatabaseParams
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -71,7 +71,7 @@ func (sql *SQL) CreateSuperuser(ctx context.Context, user, password string, allo
|
||||||
// (2) The underlying driver doesn't support "GRANT ALL PRIVILEGES"
|
// (2) The underlying driver doesn't support "GRANT ALL PRIVILEGES"
|
||||||
// See also [sql.Provision].
|
// See also [sql.Provision].
|
||||||
|
|
||||||
if !sqle.IsSafeDatabaseSingleQuote(user) || !sqle.IsSafeDatabaseSingleQuote(password) {
|
if !sqlx.IsSafeDatabaseSingleQuote(user) || !sqlx.IsSafeDatabaseSingleQuote(password) {
|
||||||
return errProvisionInvalidDatabaseParams
|
return errProvisionInvalidDatabaseParams
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -97,7 +97,7 @@ var errPurgeUser = errors.New("PurgeUser: Failed to drop user")
|
||||||
|
|
||||||
// SQLPurgeUser deletes the specified user from the database
|
// SQLPurgeUser deletes the specified user from the database
|
||||||
func (sql *SQL) PurgeUser(ctx context.Context, user string) error {
|
func (sql *SQL) PurgeUser(ctx context.Context, user string) error {
|
||||||
if !sqle.IsSafeDatabaseSingleQuote(user) {
|
if !sqlx.IsSafeDatabaseSingleQuote(user) {
|
||||||
return errPurgeUser
|
return errPurgeUser
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -114,7 +114,7 @@ var errSQLPurgeDB = errors.New("unable to drop database: unsafe database name")
|
||||||
|
|
||||||
// SQLPurgeDatabase deletes the specified db from the database
|
// SQLPurgeDatabase deletes the specified db from the database
|
||||||
func (sql *SQL) PurgeDatabase(db string) error {
|
func (sql *SQL) PurgeDatabase(db string) error {
|
||||||
if !sqle.IsSafeDatabaseLiteral(db) {
|
if !sqlx.IsSafeDatabaseLiteral(db) {
|
||||||
return errSQLPurgeDB
|
return errSQLPurgeDB
|
||||||
}
|
}
|
||||||
return sql.Exec("DROP DATABASE IF EXISTS `" + db + "`")
|
return sql.Exec("DROP DATABASE IF EXISTS `" + db + "`")
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ package sql
|
||||||
import (
|
import (
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/dis/component"
|
"github.com/FAU-CDI/wisski-distillery/internal/dis/component"
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/models"
|
"github.com/FAU-CDI/wisski-distillery/internal/models"
|
||||||
"github.com/tkw1536/goprogram/lib/reflectx"
|
"github.com/tkw1536/pkglib/reflectx"
|
||||||
)
|
)
|
||||||
|
|
||||||
// This file defines additional tables used by multiple components
|
// This file defines additional tables used by multiple components
|
||||||
|
|
|
||||||
|
|
@ -9,10 +9,10 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/FAU-CDI/wisski-distillery/pkg/logging"
|
"github.com/FAU-CDI/wisski-distillery/pkg/logging"
|
||||||
"github.com/FAU-CDI/wisski-distillery/pkg/sqle"
|
|
||||||
"github.com/FAU-CDI/wisski-distillery/pkg/timex"
|
|
||||||
"github.com/tkw1536/goprogram/exit"
|
"github.com/tkw1536/goprogram/exit"
|
||||||
"github.com/tkw1536/goprogram/stream"
|
"github.com/tkw1536/goprogram/stream"
|
||||||
|
"github.com/tkw1536/pkglib/sqlx"
|
||||||
|
"github.com/tkw1536/pkglib/timex"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Shell runs a mysql shell with the provided databases.
|
// Shell runs a mysql shell with the provided databases.
|
||||||
|
|
@ -65,7 +65,7 @@ func (sql *SQL) Update(ctx context.Context, progress io.Writer) error {
|
||||||
// create the admin user
|
// create the admin user
|
||||||
logging.LogMessage(progress, ctx, "Creating sql database")
|
logging.LogMessage(progress, ctx, "Creating sql database")
|
||||||
{
|
{
|
||||||
if !sqle.IsSafeDatabaseLiteral(sql.Config.SQL.Database) {
|
if !sqlx.IsSafeDatabaseLiteral(sql.Config.SQL.Database) {
|
||||||
return errSQLUnsafeDatabaseName
|
return errSQLUnsafeDatabaseName
|
||||||
}
|
}
|
||||||
createDBSQL := fmt.Sprintf("CREATE DATABASE IF NOT EXISTS `%s`;", sql.Config.SQL.Database)
|
createDBSQL := fmt.Sprintf("CREATE DATABASE IF NOT EXISTS `%s`;", sql.Config.SQL.Database)
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ import (
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/dis/component"
|
"github.com/FAU-CDI/wisski-distillery/internal/dis/component"
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/models"
|
"github.com/FAU-CDI/wisski-distillery/internal/models"
|
||||||
"github.com/gliderlabs/ssh"
|
"github.com/gliderlabs/ssh"
|
||||||
"github.com/tkw1536/goprogram/lib/reflectx"
|
"github.com/tkw1536/pkglib/reflectx"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (ssh2 *SSHKeys) TableInfo() component.TableInfo {
|
func (ssh2 *SSHKeys) TableInfo() component.TableInfo {
|
||||||
|
|
|
||||||
|
|
@ -12,10 +12,10 @@ import (
|
||||||
"github.com/FAU-CDI/wisski-distillery/pkg/environment"
|
"github.com/FAU-CDI/wisski-distillery/pkg/environment"
|
||||||
"github.com/FAU-CDI/wisski-distillery/pkg/fsx"
|
"github.com/FAU-CDI/wisski-distillery/pkg/fsx"
|
||||||
"github.com/FAU-CDI/wisski-distillery/pkg/logging"
|
"github.com/FAU-CDI/wisski-distillery/pkg/logging"
|
||||||
"github.com/FAU-CDI/wisski-distillery/pkg/pools"
|
|
||||||
"github.com/FAU-CDI/wisski-distillery/pkg/unpack"
|
"github.com/FAU-CDI/wisski-distillery/pkg/unpack"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/tkw1536/goprogram/stream"
|
"github.com/tkw1536/goprogram/stream"
|
||||||
|
"github.com/tkw1536/pkglib/pools"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Stack represents a 'docker compose' stack living in a specific directory
|
// Stack represents a 'docker compose' stack living in a specific directory
|
||||||
|
|
|
||||||
|
|
@ -9,10 +9,10 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/FAU-CDI/wisski-distillery/pkg/pools"
|
|
||||||
"github.com/FAU-CDI/wisski-distillery/pkg/timex"
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/rs/zerolog"
|
"github.com/rs/zerolog"
|
||||||
|
"github.com/tkw1536/pkglib/pools"
|
||||||
|
"github.com/tkw1536/pkglib/timex"
|
||||||
)
|
)
|
||||||
|
|
||||||
type TriplestoreUserPayload struct {
|
type TriplestoreUserPayload struct {
|
||||||
|
|
|
||||||
|
|
@ -8,10 +8,10 @@ import (
|
||||||
_ "embed"
|
_ "embed"
|
||||||
|
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/models"
|
"github.com/FAU-CDI/wisski-distillery/internal/models"
|
||||||
"github.com/FAU-CDI/wisski-distillery/pkg/errorx"
|
|
||||||
"github.com/FAU-CDI/wisski-distillery/pkg/pools"
|
|
||||||
"github.com/FAU-CDI/wisski-distillery/pkg/unpack"
|
"github.com/FAU-CDI/wisski-distillery/pkg/unpack"
|
||||||
"github.com/tkw1536/goprogram/exit"
|
"github.com/tkw1536/goprogram/exit"
|
||||||
|
"github.com/tkw1536/pkglib/errorx"
|
||||||
|
"github.com/tkw1536/pkglib/pools"
|
||||||
)
|
)
|
||||||
|
|
||||||
var errTripleStoreFailedRepository = exit.Error{
|
var errTripleStoreFailedRepository = exit.Error{
|
||||||
|
|
|
||||||
|
|
@ -11,11 +11,11 @@ import (
|
||||||
|
|
||||||
_ "embed"
|
_ "embed"
|
||||||
|
|
||||||
"github.com/FAU-CDI/wisski-distillery/pkg/cancel"
|
|
||||||
"github.com/FAU-CDI/wisski-distillery/pkg/lazy"
|
"github.com/FAU-CDI/wisski-distillery/pkg/lazy"
|
||||||
"github.com/tkw1536/goprogram/lib/collection"
|
|
||||||
"github.com/tkw1536/goprogram/lib/nobufio"
|
|
||||||
"github.com/tkw1536/goprogram/stream"
|
"github.com/tkw1536/goprogram/stream"
|
||||||
|
"github.com/tkw1536/pkglib/collection"
|
||||||
|
"github.com/tkw1536/pkglib/contextx"
|
||||||
|
"github.com/tkw1536/pkglib/nobufio"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Server represents a server that executes PHP code.
|
// Server represents a server that executes PHP code.
|
||||||
|
|
@ -117,7 +117,7 @@ func (server *Server) MarshalEval(ctx context.Context, value any, code string) e
|
||||||
// find a delimiter for the code, and then send
|
// find a delimiter for the code, and then send
|
||||||
io.WriteString(server.in, input)
|
io.WriteString(server.in, input)
|
||||||
|
|
||||||
data, err, _ := cancel.WithContext2(ctx, func(start func()) (string, error) {
|
data, err, _ := contextx.Run2(ctx, func(start func()) (string, error) {
|
||||||
return nobufio.ReadLine(server.out)
|
return nobufio.ReadLine(server.out)
|
||||||
}, func() {
|
}, func() {
|
||||||
server.cancel()
|
server.cancel()
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/phpx"
|
"github.com/FAU-CDI/wisski-distillery/internal/phpx"
|
||||||
"github.com/FAU-CDI/wisski-distillery/pkg/pools"
|
"github.com/tkw1536/pkglib/pools"
|
||||||
"golang.org/x/exp/slices"
|
"golang.org/x/exp/slices"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,8 +6,8 @@ import (
|
||||||
|
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/models"
|
"github.com/FAU-CDI/wisski-distillery/internal/models"
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/wisski/ingredient"
|
"github.com/FAU-CDI/wisski-distillery/internal/wisski/ingredient"
|
||||||
"github.com/FAU-CDI/wisski-distillery/pkg/cancel"
|
|
||||||
"github.com/tkw1536/goprogram/exit"
|
"github.com/tkw1536/goprogram/exit"
|
||||||
|
"github.com/tkw1536/pkglib/contextx"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Locker provides facitilites for locking this WissKI instance
|
// Locker provides facitilites for locking this WissKI instance
|
||||||
|
|
@ -38,7 +38,7 @@ func (lock *Locker) TryLock(ctx context.Context) bool {
|
||||||
// TryUnlock attempts to unlock this WissKI and reports if it succeeded.
|
// TryUnlock attempts to unlock this WissKI and reports if it succeeded.
|
||||||
// An Unlock is also attempted when ctx is cancelled.
|
// An Unlock is also attempted when ctx is cancelled.
|
||||||
func (lock *Locker) TryUnlock(ctx context.Context) bool {
|
func (lock *Locker) TryUnlock(ctx context.Context) bool {
|
||||||
ctx, close := cancel.Anyways(ctx, time.Second)
|
ctx, close := contextx.Anyways(ctx, time.Second)
|
||||||
defer close()
|
defer close()
|
||||||
|
|
||||||
table, err := lock.Malt.SQL.QueryTable(ctx, lock.Malt.LockTable)
|
table, err := lock.Malt.SQL.QueryTable(ctx, lock.Malt.LockTable)
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ import (
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/wisski/ingredient/mstore"
|
"github.com/FAU-CDI/wisski-distillery/internal/wisski/ingredient/mstore"
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/wisski/ingredient/php"
|
"github.com/FAU-CDI/wisski-distillery/internal/wisski/ingredient/php"
|
||||||
"github.com/FAU-CDI/wisski-distillery/pkg/fsx"
|
"github.com/FAU-CDI/wisski-distillery/pkg/fsx"
|
||||||
"github.com/tkw1536/goprogram/lib/collection"
|
"github.com/tkw1536/pkglib/collection"
|
||||||
|
|
||||||
_ "embed"
|
_ "embed"
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ import (
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/wisski/ingredient"
|
"github.com/FAU-CDI/wisski-distillery/internal/wisski/ingredient"
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/wisski/liquid"
|
"github.com/FAU-CDI/wisski-distillery/internal/wisski/liquid"
|
||||||
"github.com/FAU-CDI/wisski-distillery/pkg/lazy"
|
"github.com/FAU-CDI/wisski-distillery/pkg/lazy"
|
||||||
"github.com/tkw1536/goprogram/lib/collection"
|
"github.com/tkw1536/pkglib/collection"
|
||||||
)
|
)
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
|
||||||
|
|
@ -1,70 +0,0 @@
|
||||||
package cancel
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/FAU-CDI/wisski-distillery/pkg/timex"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Anyways behaves like context.WithTimeout, except that if the Done() channel of ctx is closed before Anyways is called, the returned context's Done() channel is only closed after timeout.
|
|
||||||
func Anyways(ctx context.Context, timeout time.Duration) (context.Context, context.CancelFunc) {
|
|
||||||
// context is not yet cancelled => return as-is
|
|
||||||
if err := ctx.Err(); err == nil {
|
|
||||||
return context.WithTimeout(ctx, timeout)
|
|
||||||
}
|
|
||||||
|
|
||||||
// create a new anyways
|
|
||||||
any := &anyways{
|
|
||||||
done: make(chan struct{}),
|
|
||||||
parent: ctx,
|
|
||||||
deadline: time.Now().Add(timeout),
|
|
||||||
}
|
|
||||||
|
|
||||||
// start waiting for the timer (or the cancel to be called)
|
|
||||||
finish := make(chan struct{})
|
|
||||||
go func() {
|
|
||||||
t := timex.NewTimer()
|
|
||||||
t.Reset(timeout)
|
|
||||||
defer timex.ReleaseTimer(t)
|
|
||||||
|
|
||||||
defer close(any.done)
|
|
||||||
|
|
||||||
select {
|
|
||||||
case <-t.C:
|
|
||||||
case <-finish:
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
return any, func() {
|
|
||||||
close(finish)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
type anyways struct {
|
|
||||||
done chan struct{}
|
|
||||||
|
|
||||||
parent context.Context
|
|
||||||
deadline time.Time
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a anyways) Deadline() (deadline time.Time, ok bool) {
|
|
||||||
return a.deadline, true
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a anyways) Done() <-chan struct{} {
|
|
||||||
return a.done
|
|
||||||
}
|
|
||||||
func (a anyways) Err() error {
|
|
||||||
select {
|
|
||||||
case <-a.done:
|
|
||||||
return context.DeadlineExceeded
|
|
||||||
default:
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a anyways) Value(key any) any {
|
|
||||||
return a.parent.Done()
|
|
||||||
}
|
|
||||||
|
|
@ -1,56 +0,0 @@
|
||||||
package cancel
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
)
|
|
||||||
|
|
||||||
// WithContext executes f and returns the returns the return value and nil.
|
|
||||||
//
|
|
||||||
// If the context is closed before f returns, invokes cancel and returns f(), ctx.Err().
|
|
||||||
//
|
|
||||||
// In general, WithContext always waits for f() to return even if cancel was called.
|
|
||||||
// As a special case if a closed context is passed, f is not invoked.
|
|
||||||
//
|
|
||||||
// allowcancel must be called by f exactly once, as soon as the cancel function may be invoked.
|
|
||||||
func WithContext[T any](ctx context.Context, f func(allowcancel func()) T, cancel func()) (t T, err error) {
|
|
||||||
t, _, err = WithContext2(ctx, func(start func()) (T, struct{}) {
|
|
||||||
return f(start), struct{}{}
|
|
||||||
}, cancel)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithContext2 is exactly like WithContext, but takes a function returning two parameters.
|
|
||||||
func WithContext2[T1, T2 any](ctx context.Context, f func(start func()) (T1, T2), cancel func()) (t1 T1, t2 T2, err error) {
|
|
||||||
// context is already closed, don't even try invoking it.
|
|
||||||
if err := ctx.Err(); err != nil {
|
|
||||||
return t1, t2, err
|
|
||||||
}
|
|
||||||
|
|
||||||
cancelable := make(chan struct{}, 1)
|
|
||||||
|
|
||||||
done := make(chan struct{})
|
|
||||||
go func() {
|
|
||||||
defer close(done)
|
|
||||||
defer close(cancelable)
|
|
||||||
|
|
||||||
t1, t2 = f(func() {
|
|
||||||
cancelable <- struct{}{}
|
|
||||||
})
|
|
||||||
}()
|
|
||||||
|
|
||||||
select {
|
|
||||||
case <-done:
|
|
||||||
// the function has exited regularly
|
|
||||||
// nothing to be done
|
|
||||||
case <-ctx.Done():
|
|
||||||
|
|
||||||
// context was cancelled
|
|
||||||
<-cancelable
|
|
||||||
cancel()
|
|
||||||
|
|
||||||
// still wait for it to be done!
|
|
||||||
<-done
|
|
||||||
err = ctx.Err()
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
@ -1,57 +0,0 @@
|
||||||
package cancel
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"io"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
type SetDeadline interface {
|
|
||||||
SetDeadline(t time.Time)
|
|
||||||
}
|
|
||||||
|
|
||||||
type SetReadDeadline interface {
|
|
||||||
SetReadDeadline(t time.Time) error
|
|
||||||
}
|
|
||||||
|
|
||||||
type SetWriteDeadline interface {
|
|
||||||
SetWriteDeadline(t time.Time) error
|
|
||||||
}
|
|
||||||
|
|
||||||
// Copy reads from src, and copies to dst.
|
|
||||||
//
|
|
||||||
// If the context is closed before src is closed, attempts to close the underlying reader and writer.
|
|
||||||
func Copy(ctx context.Context, dst io.Writer, src io.Reader) (written int64, err error) {
|
|
||||||
|
|
||||||
// if the context has a deadline, the propanate that deadline to the underyling file.
|
|
||||||
// this might cause the read call to not block.
|
|
||||||
if deadline, ok := ctx.Deadline(); ok {
|
|
||||||
var zero time.Time
|
|
||||||
|
|
||||||
if file, ok := src.(SetReadDeadline); ok {
|
|
||||||
file.SetReadDeadline(deadline)
|
|
||||||
defer file.SetReadDeadline(zero)
|
|
||||||
} else if file, ok := src.(SetDeadline); ok {
|
|
||||||
file.SetDeadline(deadline)
|
|
||||||
defer file.SetDeadline(zero)
|
|
||||||
}
|
|
||||||
|
|
||||||
if file, ok := dst.(SetWriteDeadline); ok {
|
|
||||||
file.SetWriteDeadline(deadline)
|
|
||||||
defer file.SetWriteDeadline(zero)
|
|
||||||
} else if file, ok := dst.(SetDeadline); ok {
|
|
||||||
file.SetDeadline(deadline)
|
|
||||||
defer file.SetDeadline(zero)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
written, err, _ = WithContext2(ctx, func(start func()) (int64, error) {
|
|
||||||
start()
|
|
||||||
return io.Copy(dst, src)
|
|
||||||
}, func() {
|
|
||||||
if closer, ok := src.(io.Closer); ok {
|
|
||||||
closer.Close()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
return written, err
|
|
||||||
}
|
|
||||||
|
|
@ -1,24 +0,0 @@
|
||||||
package cancel
|
|
||||||
|
|
||||||
import "context"
|
|
||||||
|
|
||||||
// ValuesOf returns a new context that has the same deadline and cancelation behviour as parent.
|
|
||||||
// However when requesting values from the context, checks the values in context first.
|
|
||||||
func ValuesOf(parent, values context.Context) context.Context {
|
|
||||||
return &valuesOf{
|
|
||||||
Context: parent,
|
|
||||||
values: values,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type valuesOf struct {
|
|
||||||
context.Context
|
|
||||||
values context.Context
|
|
||||||
}
|
|
||||||
|
|
||||||
func (vv *valuesOf) Value(key any) any {
|
|
||||||
if value := vv.values.Value(key); value != nil {
|
|
||||||
return value
|
|
||||||
}
|
|
||||||
return vv.Context.Value(key)
|
|
||||||
}
|
|
||||||
|
|
@ -1,62 +0,0 @@
|
||||||
package countwriter
|
|
||||||
|
|
||||||
import (
|
|
||||||
"io"
|
|
||||||
)
|
|
||||||
|
|
||||||
// CountWriter wraps an io.Writer, see [NewCountWriter].
|
|
||||||
//
|
|
||||||
// It is intended to be used to count different writes to an underlying writer.
|
|
||||||
// Once an error occurs, no more writes are passed through, and the underlying error is returned instead.
|
|
||||||
// This means that in practice, calls to write can be continued and are ignored silently.
|
|
||||||
//
|
|
||||||
// The underlying sum of bytes written and error can be seen using [Sum].
|
|
||||||
type CountWriter struct {
|
|
||||||
w io.Writer
|
|
||||||
|
|
||||||
n int
|
|
||||||
err error
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewCountWriter creates a new [CountWriter] that delegates to w.
|
|
||||||
func NewCountWriter(w io.Writer) *CountWriter {
|
|
||||||
return &CountWriter{w: w}
|
|
||||||
}
|
|
||||||
|
|
||||||
// write performs the write operation w on this writer.
|
|
||||||
func (cw *CountWriter) write(w func() (int, error)) (int, error) {
|
|
||||||
// if there was an error, return it and don't do a write
|
|
||||||
if cw.err != nil {
|
|
||||||
return 0, cw.err
|
|
||||||
}
|
|
||||||
|
|
||||||
// call the writer
|
|
||||||
n, err := w()
|
|
||||||
|
|
||||||
// update the underling state
|
|
||||||
cw.n += n
|
|
||||||
cw.err = err
|
|
||||||
|
|
||||||
// and return
|
|
||||||
return n, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write implements [io.Writer]
|
|
||||||
func (cw *CountWriter) Write(p []byte) (int, error) {
|
|
||||||
return cw.write(func() (int, error) {
|
|
||||||
return cw.w.Write(p)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// WriteString implements [io.WriteString].
|
|
||||||
// See [Write].
|
|
||||||
func (cw *CountWriter) WriteString(s string) (int, error) {
|
|
||||||
return cw.write(func() (int, error) {
|
|
||||||
return io.WriteString(cw.w, s)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sum returns the state, that is the total number of bytes written and any error
|
|
||||||
func (cw *CountWriter) Sum() (int, error) {
|
|
||||||
return cw.n, cw.err
|
|
||||||
}
|
|
||||||
|
|
@ -6,8 +6,8 @@ import (
|
||||||
"io/fs"
|
"io/fs"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"github.com/FAU-CDI/wisski-distillery/pkg/pools"
|
|
||||||
"github.com/tkw1536/goprogram/stream"
|
"github.com/tkw1536/goprogram/stream"
|
||||||
|
"github.com/tkw1536/pkglib/pools"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ExecCommandError is returned by Exec when a command could not be executed.
|
// ExecCommandError is returned by Exec when a command could not be executed.
|
||||||
|
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
package errorx
|
|
||||||
|
|
||||||
import "github.com/tkw1536/goprogram/lib/collection"
|
|
||||||
|
|
||||||
// First returns the first non-nil error, or nil otherwise.
|
|
||||||
func First(errors ...error) error {
|
|
||||||
return collection.First(errors, func(err error) bool { return err != nil })
|
|
||||||
}
|
|
||||||
|
|
@ -6,8 +6,8 @@ import (
|
||||||
"io/fs"
|
"io/fs"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
"github.com/FAU-CDI/wisski-distillery/pkg/cancel"
|
|
||||||
"github.com/FAU-CDI/wisski-distillery/pkg/environment"
|
"github.com/FAU-CDI/wisski-distillery/pkg/environment"
|
||||||
|
"github.com/tkw1536/pkglib/contextx"
|
||||||
)
|
)
|
||||||
|
|
||||||
var ErrCopySameFile = errors.New("src and dst must be different")
|
var ErrCopySameFile = errors.New("src and dst must be different")
|
||||||
|
|
@ -47,7 +47,7 @@ func CopyFile(ctx context.Context, env environment.Environment, dst, src string)
|
||||||
defer dstFile.Close()
|
defer dstFile.Close()
|
||||||
|
|
||||||
// and do the copy!
|
// and do the copy!
|
||||||
_, err = cancel.Copy(ctx, dstFile, srcFile)
|
_, err = contextx.Copy(ctx, dstFile, srcFile)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,34 +0,0 @@
|
||||||
// Package hostname provides the hostname.
|
|
||||||
package hostname
|
|
||||||
|
|
||||||
import (
|
|
||||||
"os"
|
|
||||||
|
|
||||||
"github.com/FAU-CDI/wisski-distillery/pkg/environment"
|
|
||||||
"github.com/Showmax/go-fqdn"
|
|
||||||
)
|
|
||||||
|
|
||||||
// FQDN attempts to return the fully qualified domain name of the host system.
|
|
||||||
// If an error occurs, may fall back to the empty string.
|
|
||||||
func FQDN(env environment.Environment) string {
|
|
||||||
// TODO: Pass this through!
|
|
||||||
|
|
||||||
// try the hostname function
|
|
||||||
{
|
|
||||||
fqdn, err := fqdn.FqdnHostname()
|
|
||||||
if err == nil {
|
|
||||||
return fqdn
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// fallback to os hostname
|
|
||||||
{
|
|
||||||
hostname, err := os.Hostname()
|
|
||||||
if err == nil {
|
|
||||||
return hostname
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// use the empty string
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
@ -7,8 +7,8 @@ import (
|
||||||
_ "embed"
|
_ "embed"
|
||||||
|
|
||||||
"github.com/FAU-CDI/wisski-distillery/pkg/httpx/field"
|
"github.com/FAU-CDI/wisski-distillery/pkg/httpx/field"
|
||||||
"github.com/FAU-CDI/wisski-distillery/pkg/pools"
|
|
||||||
"github.com/gorilla/csrf"
|
"github.com/gorilla/csrf"
|
||||||
|
"github.com/tkw1536/pkglib/pools"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Form provides a form that a user can submit via a http POST method call.
|
// Form provides a form that a user can submit via a http POST method call.
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,8 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/FAU-CDI/wisski-distillery/pkg/timex"
|
|
||||||
"github.com/rs/zerolog"
|
"github.com/rs/zerolog"
|
||||||
|
"github.com/tkw1536/pkglib/timex"
|
||||||
)
|
)
|
||||||
|
|
||||||
const HTMLFlushInterval = time.Second / 10
|
const HTMLFlushInterval = time.Second / 10
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ package lazy
|
||||||
import (
|
import (
|
||||||
"reflect"
|
"reflect"
|
||||||
|
|
||||||
"github.com/tkw1536/goprogram/lib/reflectx"
|
"github.com/tkw1536/pkglib/reflectx"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Pool represents a pool of laziliy initialized and potentially referencing Component instances.
|
// Pool represents a pool of laziliy initialized and potentially referencing Component instances.
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ package lazy
|
||||||
import (
|
import (
|
||||||
"reflect"
|
"reflect"
|
||||||
|
|
||||||
"github.com/tkw1536/goprogram/lib/collection"
|
"github.com/tkw1536/pkglib/collection"
|
||||||
"golang.org/x/exp/slices"
|
"golang.org/x/exp/slices"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,8 @@ package lazy
|
||||||
import (
|
import (
|
||||||
"reflect"
|
"reflect"
|
||||||
|
|
||||||
"github.com/tkw1536/goprogram/lib/collection"
|
"github.com/tkw1536/pkglib/collection"
|
||||||
"github.com/tkw1536/goprogram/lib/reflectx"
|
"github.com/tkw1536/pkglib/reflectx"
|
||||||
)
|
)
|
||||||
|
|
||||||
// getMeta gets the component belonging to a component type
|
// getMeta gets the component belonging to a component type
|
||||||
|
|
|
||||||
154
pkg/mux/mux.go
154
pkg/mux/mux.go
|
|
@ -1,154 +0,0 @@
|
||||||
// Package mux provides mux
|
|
||||||
package mux
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"net/http"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Mux represents a mux that can handle different requests
|
|
||||||
type Mux[C any] struct {
|
|
||||||
prefixes map[string][]handler
|
|
||||||
exacts map[string][]handler
|
|
||||||
|
|
||||||
Context func(r *http.Request) C // called to set context on the given request
|
|
||||||
|
|
||||||
Panic func(panic any, w http.ResponseWriter, r *http.Request) // called on panic
|
|
||||||
NotFound http.Handler // optional handler to be called in case of a not found
|
|
||||||
}
|
|
||||||
|
|
||||||
type contextKey struct{}
|
|
||||||
|
|
||||||
var theContextKey = contextKey{}
|
|
||||||
|
|
||||||
type handler struct {
|
|
||||||
Predicate Predicate
|
|
||||||
http.Handler
|
|
||||||
}
|
|
||||||
|
|
||||||
func (mux *Mux[T]) Prepare(r *http.Request) *http.Request {
|
|
||||||
if mux == nil || mux.Context == nil {
|
|
||||||
return r
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx := context.WithValue(r.Context(), theContextKey, mux.Context(r))
|
|
||||||
return r.WithContext(ctx)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (mux *Mux[T]) ContextOf(r *http.Request) (t T) {
|
|
||||||
value, ok := r.Context().Value(theContextKey).(T)
|
|
||||||
if !ok {
|
|
||||||
return t
|
|
||||||
}
|
|
||||||
return value
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add adds a handler for the given path
|
|
||||||
func (mux *Mux[T]) Add(path string, predicate Predicate, exact bool, h http.Handler) {
|
|
||||||
if mux.exacts == nil {
|
|
||||||
mux.exacts = make(map[string][]handler)
|
|
||||||
}
|
|
||||||
if mux.prefixes == nil {
|
|
||||||
mux.prefixes = make(map[string][]handler)
|
|
||||||
}
|
|
||||||
|
|
||||||
mPath := NormalizePath(path)
|
|
||||||
mHandler := handler{Predicate: predicate, Handler: h}
|
|
||||||
if exact {
|
|
||||||
mux.exacts[mPath] = append(mux.exacts[mPath], mHandler)
|
|
||||||
} else {
|
|
||||||
mux.prefixes[mPath] = append(mux.prefixes[mPath], mHandler)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Match returns the handler to be applied for the given request.
|
|
||||||
func (mux *Mux[T]) Match(r *http.Request, prepare bool) (http.Handler, bool) {
|
|
||||||
if mux == nil {
|
|
||||||
return nil, false
|
|
||||||
}
|
|
||||||
|
|
||||||
if prepare {
|
|
||||||
r = mux.Prepare(r)
|
|
||||||
}
|
|
||||||
|
|
||||||
candidate := NormalizePath(r.URL.Path)
|
|
||||||
|
|
||||||
// match the exact path first
|
|
||||||
for _, h := range mux.exacts[candidate] {
|
|
||||||
if h.Predicate.Call(r) {
|
|
||||||
return h.Handler, true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// iterate over path segment candidates
|
|
||||||
for {
|
|
||||||
// check the current candidate
|
|
||||||
for _, h := range mux.prefixes[candidate] {
|
|
||||||
if h.Predicate.Call(r) {
|
|
||||||
return h.Handler, true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// if the candidate is the root url, we can bail out now
|
|
||||||
if len(candidate) == 0 || candidate == "/" {
|
|
||||||
return nil, false
|
|
||||||
}
|
|
||||||
|
|
||||||
// move to the parent segment
|
|
||||||
candidate = parentSegment(candidate)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func (mux *Mux[T]) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|
||||||
// handle panics with the panic handler
|
|
||||||
defer func() {
|
|
||||||
caught := recover()
|
|
||||||
if caught == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if mux == nil || mux.Panic == nil {
|
|
||||||
http.Error(w, "Internal Server Error", http.StatusInternalServerError)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// silently ignore any panic()s in the panic handler
|
|
||||||
defer func() {
|
|
||||||
recover()
|
|
||||||
}()
|
|
||||||
|
|
||||||
// call the panic handler
|
|
||||||
mux.Panic(caught, w, r)
|
|
||||||
}()
|
|
||||||
|
|
||||||
// prepare the request
|
|
||||||
r = mux.Prepare(r)
|
|
||||||
|
|
||||||
// find the right handler
|
|
||||||
// or go into 404 mode
|
|
||||||
handler, ok := mux.Match(r, false)
|
|
||||||
if !ok {
|
|
||||||
if mux == nil || mux.NotFound == nil {
|
|
||||||
http.NotFound(w, r)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
mux.NotFound.ServeHTTP(w, r)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// call the actual handling
|
|
||||||
handler.ServeHTTP(w, r)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Predicate represents a matching predicate for a given request.
|
|
||||||
// The nil predicate always matches
|
|
||||||
type Predicate func(r *http.Request) bool
|
|
||||||
|
|
||||||
// Call checks if this predicate matches the given request.
|
|
||||||
func (p Predicate) Call(r *http.Request) bool {
|
|
||||||
if p == nil {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return p(r)
|
|
||||||
}
|
|
||||||
|
|
@ -1,28 +0,0 @@
|
||||||
package mux
|
|
||||||
|
|
||||||
import (
|
|
||||||
"path"
|
|
||||||
)
|
|
||||||
|
|
||||||
// NormalizePath normalizes the provided path.
|
|
||||||
// It ensures that there is both a leading and trailing slash.
|
|
||||||
func NormalizePath(value string) string {
|
|
||||||
value = path.Clean(value)
|
|
||||||
if value != "/" {
|
|
||||||
value = value + "/"
|
|
||||||
}
|
|
||||||
return value
|
|
||||||
}
|
|
||||||
|
|
||||||
// parentSegment returns the parent segment of the provided path
|
|
||||||
// it assumes that normalizePath has been called on value.
|
|
||||||
func parentSegment(value string) string {
|
|
||||||
if value == "" || value == "/" {
|
|
||||||
return "/"
|
|
||||||
}
|
|
||||||
parent := path.Dir(value[:len(value)-1])
|
|
||||||
if parent != "/" {
|
|
||||||
parent = parent + "/"
|
|
||||||
}
|
|
||||||
return parent
|
|
||||||
}
|
|
||||||
|
|
@ -5,7 +5,7 @@ import (
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"math/big"
|
"math/big"
|
||||||
|
|
||||||
"github.com/FAU-CDI/wisski-distillery/pkg/pools"
|
"github.com/tkw1536/pkglib/pools"
|
||||||
)
|
)
|
||||||
|
|
||||||
// NOTE(twiesing): A bunch of scripts cannot properly handle the extra characters in the password.
|
// NOTE(twiesing): A bunch of scripts cannot properly handle the extra characters in the password.
|
||||||
|
|
|
||||||
|
|
@ -1,34 +0,0 @@
|
||||||
// Package pools holds various pools for reuse
|
|
||||||
package pools
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"strings"
|
|
||||||
"sync"
|
|
||||||
)
|
|
||||||
|
|
||||||
var builders = sync.Pool{
|
|
||||||
New: func() any { return new(strings.Builder) },
|
|
||||||
}
|
|
||||||
|
|
||||||
func GetBuilder() *strings.Builder {
|
|
||||||
return builders.Get().(*strings.Builder)
|
|
||||||
}
|
|
||||||
|
|
||||||
func ReleaseBuilder(builder *strings.Builder) {
|
|
||||||
builder.Reset()
|
|
||||||
builders.Put(builder)
|
|
||||||
}
|
|
||||||
|
|
||||||
var buffers = sync.Pool{
|
|
||||||
New: func() any { return new(bytes.Buffer) },
|
|
||||||
}
|
|
||||||
|
|
||||||
func GetBuffer() *bytes.Buffer {
|
|
||||||
return buffers.Get().(*bytes.Buffer)
|
|
||||||
}
|
|
||||||
|
|
||||||
func ReleaseBuffer(buffer *bytes.Buffer) {
|
|
||||||
buffer.Reset()
|
|
||||||
buffers.Put(buffer)
|
|
||||||
}
|
|
||||||
|
|
@ -1,108 +0,0 @@
|
||||||
package spawner
|
|
||||||
|
|
||||||
import (
|
|
||||||
"io"
|
|
||||||
"log"
|
|
||||||
"sync"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Spawner[T io.Closer] struct {
|
|
||||||
Spawn func() T
|
|
||||||
Alive func(t T) bool
|
|
||||||
|
|
||||||
Limit int
|
|
||||||
|
|
||||||
initOnce sync.Once
|
|
||||||
wg sync.WaitGroup
|
|
||||||
tasks chan task[T]
|
|
||||||
|
|
||||||
instances []T
|
|
||||||
alive []bool
|
|
||||||
}
|
|
||||||
|
|
||||||
type task[T any] struct {
|
|
||||||
f func(t T)
|
|
||||||
done chan<- struct{}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (tt task[T]) Do(t T) {
|
|
||||||
defer close(tt.done)
|
|
||||||
tt.f(t)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (spawner *Spawner[T]) worker(i int) {
|
|
||||||
spawner.wg.Add(1)
|
|
||||||
go func() {
|
|
||||||
defer spawner.wg.Done()
|
|
||||||
|
|
||||||
var zero T
|
|
||||||
for task := range spawner.tasks {
|
|
||||||
// spawn a new instance once finished
|
|
||||||
if !spawner.alive[i] {
|
|
||||||
log.Println("respawning instance ", i)
|
|
||||||
spawner.instances[i] = spawner.Spawn()
|
|
||||||
spawner.alive[i] = true
|
|
||||||
}
|
|
||||||
|
|
||||||
task.Do(spawner.instances[i])
|
|
||||||
|
|
||||||
// if the instance has died during execution
|
|
||||||
// then do a close (to deallocate)
|
|
||||||
if !spawner.Alive(spawner.instances[i]) {
|
|
||||||
spawner.instances[i].Close()
|
|
||||||
spawner.instances[i] = zero
|
|
||||||
spawner.alive[i] = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (spawner *Spawner[T]) start() {
|
|
||||||
spawner.initOnce.Do(func() {
|
|
||||||
limit := spawner.Limit
|
|
||||||
if limit < 1 {
|
|
||||||
limit = 1
|
|
||||||
}
|
|
||||||
|
|
||||||
spawner.tasks = make(chan task[T], limit)
|
|
||||||
spawner.alive = make([]bool, limit)
|
|
||||||
spawner.instances = make([]T, limit)
|
|
||||||
for i := 0; i < limit; i++ {
|
|
||||||
spawner.worker(i)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// Do performs f on an unspecified object from the spawner.
|
|
||||||
// If no objects are available within time.Duration, a new object is spawned as there are at most limit objects.
|
|
||||||
func (spawner *Spawner[T]) Do(f func(t T)) {
|
|
||||||
spawner.start()
|
|
||||||
|
|
||||||
done := make(chan struct{})
|
|
||||||
spawner.tasks <- task[T]{
|
|
||||||
f: f,
|
|
||||||
done: done,
|
|
||||||
}
|
|
||||||
<-done
|
|
||||||
}
|
|
||||||
|
|
||||||
func (spawner *Spawner[T]) Close() {
|
|
||||||
close(spawner.tasks)
|
|
||||||
spawner.wg.Wait()
|
|
||||||
|
|
||||||
spawner.wg.Add(len(spawner.alive))
|
|
||||||
|
|
||||||
var zero T
|
|
||||||
for i := range spawner.alive {
|
|
||||||
go func(i int) {
|
|
||||||
defer spawner.wg.Done()
|
|
||||||
|
|
||||||
if spawner.alive[i] {
|
|
||||||
spawner.instances[i].Close()
|
|
||||||
spawner.instances[i] = zero
|
|
||||||
}
|
|
||||||
}(i)
|
|
||||||
}
|
|
||||||
|
|
||||||
spawner.wg.Wait()
|
|
||||||
}
|
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -1,12 +0,0 @@
|
||||||
package sqle
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/feiin/sqlstring"
|
|
||||||
)
|
|
||||||
|
|
||||||
// TODO: This is really unsafe and shouldn't be used at all.
|
|
||||||
|
|
||||||
// Format formats the provided query with the given parameters.
|
|
||||||
func Format(query string, params ...interface{}) string {
|
|
||||||
return sqlstring.Format(query, params...)
|
|
||||||
}
|
|
||||||
|
|
@ -1,17 +0,0 @@
|
||||||
package sshx
|
|
||||||
|
|
||||||
import "github.com/gliderlabs/ssh"
|
|
||||||
|
|
||||||
// ParseAllKeys parses all keys from the list of bytes
|
|
||||||
func ParseAllKeys(bytes []byte) (keys []ssh.PublicKey) {
|
|
||||||
var key ssh.PublicKey
|
|
||||||
var err error
|
|
||||||
for {
|
|
||||||
key, _, _, bytes, err = ssh.ParseAuthorizedKey(bytes)
|
|
||||||
if err != nil {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
keys = append(keys, key)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
@ -1,91 +0,0 @@
|
||||||
// Package timex provides Interval and Wait
|
|
||||||
package timex
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"sync"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
var tPool = sync.Pool{
|
|
||||||
New: func() any {
|
|
||||||
timer := time.NewTimer(time.Second)
|
|
||||||
StopTimer(timer)
|
|
||||||
return timer
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewTimer returns an unusued timer from an internal timer pool.
|
|
||||||
// The timer is guaranteed to be stopped; meaning a call to timer.Reset() should be made before using it.
|
|
||||||
func NewTimer() *time.Timer {
|
|
||||||
return tPool.Get().(*time.Timer)
|
|
||||||
}
|
|
||||||
|
|
||||||
// StopTimer stops the given timer and drains the underlying channel.
|
|
||||||
// This prevents it from firing, until a call to Reset() is made.
|
|
||||||
//
|
|
||||||
// If the timer is not running, StopTimer does nothing.
|
|
||||||
func StopTimer(t *time.Timer) {
|
|
||||||
t.Stop()
|
|
||||||
|
|
||||||
// try to stop
|
|
||||||
select {
|
|
||||||
case <-t.C:
|
|
||||||
default:
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ReleaseTimer stops t and returns it to the pool of timers.
|
|
||||||
func ReleaseTimer(t *time.Timer) {
|
|
||||||
StopTimer(t)
|
|
||||||
tPool.Put(t)
|
|
||||||
}
|
|
||||||
|
|
||||||
// TickContext is like [time.Tick], but closes the returned channel once the context closes.
|
|
||||||
// As such it can be recovered by the garbage collector; see [time.TickContext].
|
|
||||||
//
|
|
||||||
// Unlike [time.Tick], immediatly send the current time on the given channel.
|
|
||||||
func TickContext(c context.Context, d time.Duration) <-chan time.Time {
|
|
||||||
if d < 0 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
ticker := make(chan time.Time, 1)
|
|
||||||
ticker <- time.Now()
|
|
||||||
go func() {
|
|
||||||
defer close(ticker)
|
|
||||||
|
|
||||||
timer := NewTimer()
|
|
||||||
defer ReleaseTimer(timer)
|
|
||||||
|
|
||||||
for {
|
|
||||||
timer.Reset(d)
|
|
||||||
|
|
||||||
select {
|
|
||||||
case tick := <-timer.C:
|
|
||||||
ticker <- tick
|
|
||||||
case <-c.Done():
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
return ticker
|
|
||||||
}
|
|
||||||
|
|
||||||
// TickUntilFunc invokes f every d until either context is closed, or f returns true.
|
|
||||||
// f is invoked once immediatly when the timer starts.
|
|
||||||
//
|
|
||||||
// TickUntilFunc blocks until f is no longer invoked.
|
|
||||||
//
|
|
||||||
// Returns the error of the context (if any).
|
|
||||||
func TickUntilFunc(f func(t time.Time) bool, c context.Context, d time.Duration) error {
|
|
||||||
context, cancel := context.WithCancel(c)
|
|
||||||
defer cancel()
|
|
||||||
|
|
||||||
for t := range TickContext(context, d) {
|
|
||||||
if f(t) {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return c.Err()
|
|
||||||
}
|
|
||||||
|
|
@ -1,88 +0,0 @@
|
||||||
package validator
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"reflect"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
validateTag = "validate"
|
|
||||||
recurseTag = "recurse"
|
|
||||||
dfltTag = "default"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Validate validates an object of type T, setting defaults where appropriate.
|
|
||||||
//
|
|
||||||
// T must be a struct type, when this is not the case, returns ErrNotAStruct.
|
|
||||||
// validators should contain a set of validators.
|
|
||||||
//
|
|
||||||
// Validate iterates over the fields and tags of those fields as follows:
|
|
||||||
// - If the 'validate' tag is not the empty string, read the appropriate validator from the map, and call the function.
|
|
||||||
// If the element in the validators map does not exist, returns an error that unwraps to type UnknownValidator.
|
|
||||||
// If the element in the validators map is not a validator, returns an error that unwraps to type NotAValidator.
|
|
||||||
// If the type of validator function does not match the field type, returns an error that unwraps to type IncompatibleValidator.
|
|
||||||
// - If the 'recurse' tag is not the empty string, recurse into the struct type by calling Validate on it.
|
|
||||||
// If the annotated field is not a struct, return an error.
|
|
||||||
//
|
|
||||||
// Any error is wrapped in a FieldError, indicating the field they occured in.
|
|
||||||
// Recursive validate calls may result in FieldError wraps.
|
|
||||||
// For a description of struct tags, see [reflect.StructTag].
|
|
||||||
func Validate[T any](data *T, validators map[string]any) error {
|
|
||||||
return validate(reflect.ValueOf(data).Elem(), validators)
|
|
||||||
}
|
|
||||||
|
|
||||||
// FieldError wraps an error to indicate which field it occured in.
|
|
||||||
type FieldError struct {
|
|
||||||
Field string
|
|
||||||
Err error
|
|
||||||
}
|
|
||||||
|
|
||||||
func (fe FieldError) Error() string {
|
|
||||||
return fmt.Sprintf("field %q: %s", fe.Field, fe.Err)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (fe FieldError) Unwrap() error {
|
|
||||||
return fe.Err
|
|
||||||
}
|
|
||||||
|
|
||||||
var ErrNotAStruct = errors.New("validate called on non-struct type")
|
|
||||||
|
|
||||||
func validate(datum reflect.Value, validators Collection) error {
|
|
||||||
// make sure that we have a struct type
|
|
||||||
typ := datum.Type()
|
|
||||||
if typ.Kind() != reflect.Struct {
|
|
||||||
return ErrNotAStruct
|
|
||||||
}
|
|
||||||
|
|
||||||
fieldC := typ.NumField()
|
|
||||||
for i := 0; i < fieldC; i++ {
|
|
||||||
field := typ.Field(i)
|
|
||||||
|
|
||||||
// if the recurse tag is set, do the recursion!
|
|
||||||
if field.Tag.Get(recurseTag) != "" {
|
|
||||||
if err := validate(datum.FieldByName(field.Name), validators); err != nil {
|
|
||||||
return FieldError{Field: field.Name, Err: err}
|
|
||||||
}
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
// check if there is a validator associated with this tag
|
|
||||||
// and if not, skip it!
|
|
||||||
validator := field.Tag.Get(validateTag)
|
|
||||||
if validator == "" {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
// call the actual validator
|
|
||||||
if err := validators.Call(
|
|
||||||
validator,
|
|
||||||
datum.FieldByName(field.Name),
|
|
||||||
field.Tag.Get(dfltTag),
|
|
||||||
); err != nil {
|
|
||||||
return FieldError{Field: field.Name, Err: err}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
@ -1,123 +0,0 @@
|
||||||
package validator
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"strconv"
|
|
||||||
)
|
|
||||||
|
|
||||||
func ExampleValidate() {
|
|
||||||
var value struct {
|
|
||||||
Number int `validate:"positive" default:"234"`
|
|
||||||
String string `validate:"nonempty" default:"stuff"`
|
|
||||||
Recursive struct {
|
|
||||||
Number int `validate:"positive" default:"45"`
|
|
||||||
String string `validate:"nonempty" default:"more"`
|
|
||||||
} `recurse:"true"`
|
|
||||||
}
|
|
||||||
|
|
||||||
collection := make(Collection, 2)
|
|
||||||
Add(collection, "positive", func(value *int, dflt string) error {
|
|
||||||
if *value == 0 {
|
|
||||||
i, err := strconv.ParseInt(dflt, 10, 64)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
*value = int(i)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
if *value < 0 {
|
|
||||||
return errors.New("not positive")
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
Add(collection, "nonempty", func(value *string, dflt string) error {
|
|
||||||
if *value == "" {
|
|
||||||
*value = dflt
|
|
||||||
}
|
|
||||||
if *value == "" {
|
|
||||||
return errors.New("empty string")
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
|
|
||||||
err := Validate(&value, collection)
|
|
||||||
fmt.Printf("%v\n", value)
|
|
||||||
fmt.Println(err)
|
|
||||||
// Output: {234 stuff {45 more}}
|
|
||||||
// <nil>
|
|
||||||
}
|
|
||||||
|
|
||||||
func ExampleValidate_fail() {
|
|
||||||
var value struct {
|
|
||||||
Number int `validate:"positive" default:"12"`
|
|
||||||
String string `validate:"nonempty" default:"stuff"`
|
|
||||||
Recursive struct {
|
|
||||||
Number int `validate:"positive" default:"12"`
|
|
||||||
String string `validate:"nonempty"`
|
|
||||||
} `recurse:"true"`
|
|
||||||
}
|
|
||||||
|
|
||||||
collection := make(Collection, 2)
|
|
||||||
Add(collection, "positive", func(value *int, dflt string) error {
|
|
||||||
if *value == 0 {
|
|
||||||
i, err := strconv.ParseInt(dflt, 10, 64)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
*value = int(i)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
if *value < 0 {
|
|
||||||
return errors.New("not positive")
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
Add(collection, "nonempty", func(value *string, dflt string) error {
|
|
||||||
if *value == "" {
|
|
||||||
*value = dflt
|
|
||||||
}
|
|
||||||
if *value == "" {
|
|
||||||
return errors.New("empty string")
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
|
|
||||||
err := Validate(&value, collection)
|
|
||||||
fmt.Printf("%v\n", value)
|
|
||||||
fmt.Println(err)
|
|
||||||
// Output: {12 stuff {12 }}
|
|
||||||
// field "Recursive": field "String": empty string
|
|
||||||
}
|
|
||||||
|
|
||||||
func ExampleValidate_notastruct() {
|
|
||||||
var value int
|
|
||||||
err := Validate(&value, nil)
|
|
||||||
fmt.Println(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
func ExampleValidate_notavalidator() {
|
|
||||||
var value struct {
|
|
||||||
Field int `validate:"generic"`
|
|
||||||
}
|
|
||||||
collection := make(Collection, 2)
|
|
||||||
collection["generic"] = func(x, y int) error {
|
|
||||||
panic("never reached")
|
|
||||||
}
|
|
||||||
err := Validate(&value, collection)
|
|
||||||
fmt.Println(err)
|
|
||||||
// Output: field "Field": entry "generic" in validators is not a valiator
|
|
||||||
}
|
|
||||||
|
|
||||||
func ExampleValidate_invalid() {
|
|
||||||
var value struct {
|
|
||||||
Field int `validate:"string"`
|
|
||||||
}
|
|
||||||
collection := make(Collection, 2)
|
|
||||||
collection["string"] = func(value *string, dflt string) error {
|
|
||||||
panic("never reached")
|
|
||||||
}
|
|
||||||
err := Validate(&value, collection)
|
|
||||||
fmt.Println(err)
|
|
||||||
// Output: field "Field": validator "string": got type string, expected type int
|
|
||||||
}
|
|
||||||
|
|
@ -1,131 +0,0 @@
|
||||||
package validator
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"reflect"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/tkw1536/goprogram/lib/reflectx"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Collection represents a set of validators.
|
|
||||||
// The zero value is not ready to use; it should be created using make().
|
|
||||||
//
|
|
||||||
// A validator is a non-nil function with signature func(value *F, dflt string) error.
|
|
||||||
// Here F is the type of a value of a field.
|
|
||||||
// The value is the initialized value to be validated.
|
|
||||||
// The validator may perform abitrary normalization on the value.
|
|
||||||
// dflt is the default value (read from the 'default' tag).
|
|
||||||
// error should be an appropriate error that occured.
|
|
||||||
//
|
|
||||||
// A validator function is applied by calling it.
|
|
||||||
type Collection map[string]any
|
|
||||||
|
|
||||||
// Add adds a Validator to the provided collection of validators.
|
|
||||||
// Any previously validator of the same name is overwritten.
|
|
||||||
func Add[F any](coll Collection, name string, validator func(value *F, dflt string) error) {
|
|
||||||
coll[name] = validator
|
|
||||||
}
|
|
||||||
|
|
||||||
// AddSlice adds a Validator to the provided collection of validators that validates a slice of the given type. The default is seperated by seperator.
|
|
||||||
func AddSlice[F any](coll Collection, name string, sep string, validator func(value *F, dflt string) error) {
|
|
||||||
Add(coll, name, func(value *[]F, dflt string) error {
|
|
||||||
// some value is set, so we do not need to set the default!
|
|
||||||
if *value != nil {
|
|
||||||
for i := range *value {
|
|
||||||
if err := validator(&(*value)[i], ""); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// no default provided => set if to an empty slice
|
|
||||||
if dflt == "" {
|
|
||||||
*value = make([]F, 0)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// some default provided => iterate over the underlying validator
|
|
||||||
dflts := strings.Split(dflt, sep)
|
|
||||||
*value = make([]F, len(dflts))
|
|
||||||
for i := range *value {
|
|
||||||
if err := validator(&(*value)[i], dflts[i]); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
errTyp = reflectx.TypeOf[error]()
|
|
||||||
strTyp = reflectx.TypeOf[string]()
|
|
||||||
)
|
|
||||||
|
|
||||||
// UnknownValidator is an error returned from Validate if a validator does not exist
|
|
||||||
type UnknownValidator string
|
|
||||||
|
|
||||||
func (uv UnknownValidator) Error() string {
|
|
||||||
return fmt.Sprintf("unknown validator %q", string(uv))
|
|
||||||
}
|
|
||||||
|
|
||||||
// NotAValidator is an error returned from Validate if an entry in the validators map is not a validator
|
|
||||||
type NotAValidator string
|
|
||||||
|
|
||||||
func (nv NotAValidator) Error() string {
|
|
||||||
return fmt.Sprintf("entry %q in validators is not a valiator", string(nv))
|
|
||||||
}
|
|
||||||
|
|
||||||
// IncompatibleValidator is returned when a validator in the validators map is incompatible
|
|
||||||
type IncompatibleValidator struct {
|
|
||||||
Validator string
|
|
||||||
GotType reflect.Type
|
|
||||||
ExpectedType reflect.Type
|
|
||||||
}
|
|
||||||
|
|
||||||
func (iv IncompatibleValidator) Error() string {
|
|
||||||
return fmt.Sprintf("validator %q: got type %s, expected type %s", iv.Validator, iv.GotType, iv.ExpectedType)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Call calls the validator with the given name, on the given value, and with the provided default.
|
|
||||||
// See documentation of [Validate] for details.
|
|
||||||
func (coll Collection) Call(name string, field reflect.Value, dflt string) error {
|
|
||||||
validator, ok := coll[name]
|
|
||||||
if !ok {
|
|
||||||
return UnknownValidator(name)
|
|
||||||
}
|
|
||||||
|
|
||||||
// get the type of the validator
|
|
||||||
vFunc := reflect.ValueOf(validator)
|
|
||||||
vTyp := vFunc.Type()
|
|
||||||
|
|
||||||
// ensure that vTyp is of type func(*F,string) error
|
|
||||||
// where T is the type of the field
|
|
||||||
//
|
|
||||||
// - the first if assumes checks for some type F
|
|
||||||
// - the second if checks if the F is the right one
|
|
||||||
if validator == nil || vTyp.Kind() != reflect.Func || // func
|
|
||||||
vTyp.NumIn() != 2 || vTyp.In(0).Kind() != reflect.Pointer || vTyp.In(1) != strTyp || // (*F,string)
|
|
||||||
vTyp.NumOut() != 1 || vTyp.Out(0) != errTyp { // error
|
|
||||||
return NotAValidator(name)
|
|
||||||
}
|
|
||||||
if vTyp.In(0).Elem() != field.Type() { // the correct *F
|
|
||||||
return IncompatibleValidator{
|
|
||||||
Validator: name,
|
|
||||||
GotType: vTyp.In(0).Elem(),
|
|
||||||
ExpectedType: field.Type(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// call the validator function, and return an error
|
|
||||||
results := vFunc.Call([]reflect.Value{field.Addr(), reflect.ValueOf(dflt)})
|
|
||||||
|
|
||||||
// turn the result into an error
|
|
||||||
// NOTE: We can't just .(error) here because that panic()s on err == nil
|
|
||||||
err := results[0].Interface()
|
|
||||||
if err, ok := err.(error); ok {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue