Start migrating templates
This commit is contained in:
parent
b92adff355
commit
a4e2d625a3
9
go.mod
9
go.mod
|
@ -3,10 +3,19 @@ module git.handmade.network/hmn/hmn
|
||||||
go 1.16
|
go 1.16
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
github.com/Masterminds/goutils v1.1.1 // indirect
|
||||||
|
github.com/Masterminds/semver v1.5.0 // indirect
|
||||||
|
github.com/Masterminds/sprig v2.22.0+incompatible // indirect
|
||||||
github.com/go-stack/stack v1.8.0
|
github.com/go-stack/stack v1.8.0
|
||||||
|
github.com/google/uuid v1.2.0 // indirect
|
||||||
|
github.com/huandu/xstrings v1.3.2 // indirect
|
||||||
|
github.com/imdario/mergo v0.3.12 // indirect
|
||||||
github.com/jackc/pgx/v4 v4.10.1
|
github.com/jackc/pgx/v4 v4.10.1
|
||||||
github.com/julienschmidt/httprouter v1.3.0
|
github.com/julienschmidt/httprouter v1.3.0
|
||||||
|
github.com/mitchellh/copystructure v1.1.1 // indirect
|
||||||
github.com/rs/zerolog v1.20.0
|
github.com/rs/zerolog v1.20.0
|
||||||
github.com/spf13/cobra v1.1.3
|
github.com/spf13/cobra v1.1.3
|
||||||
|
github.com/stretchr/testify v1.7.0 // indirect
|
||||||
|
github.com/teacat/noire v1.1.0 // indirect
|
||||||
github.com/wellington/go-libsass v0.9.2
|
github.com/wellington/go-libsass v0.9.2
|
||||||
)
|
)
|
||||||
|
|
24
go.sum
24
go.sum
|
@ -13,6 +13,12 @@ cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiy
|
||||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
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/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||||
|
github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI=
|
||||||
|
github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
|
||||||
|
github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww=
|
||||||
|
github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
|
||||||
|
github.com/Masterminds/sprig v2.22.0+incompatible h1:z4yfnGrZ7netVz+0EDJ0Wi+5VZCSYp4Z0m2dk6cEM60=
|
||||||
|
github.com/Masterminds/sprig v2.22.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o=
|
||||||
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
||||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||||
|
@ -69,6 +75,8 @@ github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXi
|
||||||
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||||
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||||
|
github.com/google/uuid v1.2.0 h1:qJYtXnJRWmpe7m/3XlyhrsLrEURqHRM2kxzoxXqyUDs=
|
||||||
|
github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
||||||
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
||||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||||
|
@ -96,6 +104,10 @@ github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO
|
||||||
github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ=
|
github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ=
|
||||||
github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
|
github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
|
||||||
github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
|
github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
|
||||||
|
github.com/huandu/xstrings v1.3.2 h1:L18LIDzqlW6xN2rEkpdV8+oL/IXWJ1APd+vsdYy4Wdw=
|
||||||
|
github.com/huandu/xstrings v1.3.2/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
|
||||||
|
github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU=
|
||||||
|
github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
|
||||||
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
|
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
|
||||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||||
github.com/jackc/chunkreader v1.0.0 h1:4s39bBR8ByfqH+DKm8rQA3E1LHZWB9XWcrz8fqaZbe0=
|
github.com/jackc/chunkreader v1.0.0 h1:4s39bBR8ByfqH+DKm8rQA3E1LHZWB9XWcrz8fqaZbe0=
|
||||||
|
@ -186,6 +198,8 @@ github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Ky
|
||||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||||
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
|
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
|
||||||
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
|
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
|
||||||
|
github.com/mitchellh/copystructure v1.1.1 h1:Bp6x9R1Wn16SIz3OfeDr0b7RnCG2OB66Y7PQyC/cvq4=
|
||||||
|
github.com/mitchellh/copystructure v1.1.1/go.mod h1:EBArHfARyrSWO/+Wyr9zwEkc6XMFB9XyNgFNmRkZZU4=
|
||||||
github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||||
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||||
github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
|
github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
|
||||||
|
@ -193,6 +207,8 @@ github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS4
|
||||||
github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY=
|
github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY=
|
||||||
github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||||
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||||
|
github.com/mitchellh/reflectwalk v1.0.1 h1:FVzMWA5RllMAKIdUSC8mdWo3XtwoecrH79BY70sEEpE=
|
||||||
|
github.com/mitchellh/reflectwalk v1.0.1/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
|
||||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||||
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||||
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||||
|
@ -253,7 +269,12 @@ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UV
|
||||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||||
github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4=
|
github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4=
|
||||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||||
|
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
|
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
||||||
|
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
|
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
|
||||||
|
github.com/teacat/noire v1.1.0 h1:5IgJ1H8jodiSSYnrVadV2JjbAnEgCCjYUQxSUuaQ7Sg=
|
||||||
|
github.com/teacat/noire v1.1.0/go.mod h1:cetGlnqr+9yKJcFgRgYXOWJY66XIrrjUsGBwNlNNtAk=
|
||||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||||
github.com/wellington/go-libsass v0.9.2 h1:6Ims04UDdBs6/CGSVK5JC8FNikR5ssrsMMKE/uaO5Q8=
|
github.com/wellington/go-libsass v0.9.2 h1:6Ims04UDdBs6/CGSVK5JC8FNikR5ssrsMMKE/uaO5Q8=
|
||||||
github.com/wellington/go-libsass v0.9.2/go.mod h1:mxgxgam0N0E+NAUMHLcu20Ccfc3mVpDkyrLDayqfiTs=
|
github.com/wellington/go-libsass v0.9.2/go.mod h1:mxgxgam0N0E+NAUMHLcu20Ccfc3mVpDkyrLDayqfiTs=
|
||||||
|
@ -409,8 +430,11 @@ gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bl
|
||||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
|
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||||
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
|
||||||
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
|
|
9610
public/style.css
9610
public/style.css
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -1,11 +1,13 @@
|
||||||
package buildscss
|
package buildscss
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/base64"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
"git.handmade.network/hmn/hmn/src/color"
|
color "git.handmade.network/hmn/hmn/src/ansicolor"
|
||||||
"git.handmade.network/hmn/hmn/src/oops"
|
"git.handmade.network/hmn/hmn/src/oops"
|
||||||
"git.handmade.network/hmn/hmn/src/website"
|
"git.handmade.network/hmn/hmn/src/website"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
@ -15,6 +17,22 @@ import (
|
||||||
var compressed bool
|
var compressed bool
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
libsass.RegisterSassFunc("base64($filename)", func(ctx context.Context, in libsass.SassValue) (*libsass.SassValue, error) {
|
||||||
|
var filename string
|
||||||
|
err := libsass.Unmarshal(in, &filename)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
fileBytes, err := os.ReadFile(filename)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
encoded, _ := libsass.Marshal(base64.StdEncoding.EncodeToString(fileBytes))
|
||||||
|
return &encoded, nil
|
||||||
|
})
|
||||||
|
|
||||||
buildCommand := &cobra.Command{
|
buildCommand := &cobra.Command{
|
||||||
Use: "buildscss",
|
Use: "buildscss",
|
||||||
Short: "Build the website CSS",
|
Short: "Build the website CSS",
|
||||||
|
|
|
@ -7,7 +7,7 @@ import (
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"git.handmade.network/hmn/hmn/src/color"
|
color "git.handmade.network/hmn/hmn/src/ansicolor"
|
||||||
"git.handmade.network/hmn/hmn/src/oops"
|
"git.handmade.network/hmn/hmn/src/oops"
|
||||||
"github.com/rs/zerolog"
|
"github.com/rs/zerolog"
|
||||||
"github.com/rs/zerolog/log"
|
"github.com/rs/zerolog/log"
|
||||||
|
@ -38,6 +38,14 @@ func Error() *zerolog.Event {
|
||||||
return log.Error().Timestamp().Stack()
|
return log.Error().Timestamp().Stack()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Panic() *zerolog.Event {
|
||||||
|
return log.Panic().Timestamp().Stack()
|
||||||
|
}
|
||||||
|
|
||||||
|
func Fatal() *zerolog.Event {
|
||||||
|
return log.Fatal().Timestamp().Stack()
|
||||||
|
}
|
||||||
|
|
||||||
type PrettyZerologWriter struct {
|
type PrettyZerologWriter struct {
|
||||||
wd string
|
wd string
|
||||||
}
|
}
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 2.1 KiB |
Binary file not shown.
After Width: | Height: | Size: 2.1 KiB |
|
@ -2,6 +2,6 @@
|
||||||
.gradient {
|
.gradient {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 114px;
|
height: 114px;
|
||||||
background-image: linear-gradient(rgba(0, 0, 0, 0.82), #0000);
|
background-image: linear-gradient(rgba(0, 0, 0, 0.82), rgba(0, 0, 0, 0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
I'm a footer~!
|
|
@ -0,0 +1 @@
|
||||||
|
I'm a header!
|
|
@ -0,0 +1,5 @@
|
||||||
|
{{ template "base.html" . }}
|
||||||
|
|
||||||
|
{{ define "content" }}
|
||||||
|
This is the index page.
|
||||||
|
{{ end }}
|
|
@ -0,0 +1,73 @@
|
||||||
|
<!DOCTYPE html{{ if .OpenGraphItems }} prefix="og: http://ogp.me/ns#"{{ end }}>
|
||||||
|
<html lang="en-US">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
{{ if .CanonicalLink }}<link rel="canonical" href="{{ .CanonicalLink }}">{{ end }}
|
||||||
|
{{ range .OpenGraphItems }}
|
||||||
|
{{ if .Property }}
|
||||||
|
<meta property="{{ .Property }}" content="{{ .Value }}" />
|
||||||
|
{{ else }}
|
||||||
|
<meta name="{{ .Name }}" content="{{ .Value }}" />
|
||||||
|
{{ end }}
|
||||||
|
{{ end }}
|
||||||
|
{{ if .Title }}
|
||||||
|
<title>{{ .Title }} | Handmade Network</title>
|
||||||
|
{{ else }}
|
||||||
|
<title>Handmade Network</title>
|
||||||
|
{{ end }}
|
||||||
|
<link href='https://fonts.googleapis.com/css?family=Fira+Sans:300,400,500,600' rel='stylesheet' type='text/css'>
|
||||||
|
<link href='https://fonts.googleapis.com/css?family=Fira+Mono:300,400,500,700' rel='stylesheet' type='text/css'>
|
||||||
|
<link rel="stylesheet" type="text/css" href="{{ static "css/style.css" }}" />
|
||||||
|
{{/* TODO: These are the base64 encodings of bglight.png and bgdark.png. Rather than manually putting the encoding here, it would be nice to automatically calculate it when the server starts up and pass it in. */}}
|
||||||
|
{{ $bglight := "iVBORw0KGgoAAAANSUhEUgAAAEgAAABICAYAAABV7bNHAAAEGGlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4KPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iWE1QIENvcmUgNS41LjAiPgogPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgeG1sbnM6ZXhpZj0iaHR0cDovL25zLmFkb2JlLmNvbS9leGlmLzEuMC8iCiAgICB4bWxuczp0aWZmPSJodHRwOi8vbnMuYWRvYmUuY29tL3RpZmYvMS4wLyIKICAgIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyIKICAgIHhtbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIgogICAgeG1sbnM6c3RFdnQ9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZUV2ZW50IyIKICAgZXhpZjpQaXhlbFhEaW1lbnNpb249IjcyIgogICBleGlmOlBpeGVsWURpbWVuc2lvbj0iNzIiCiAgIHRpZmY6SW1hZ2VXaWR0aD0iNzIiCiAgIHRpZmY6SW1hZ2VMZW5ndGg9IjcyIgogICB0aWZmOlJlc29sdXRpb25Vbml0PSIyIgogICB0aWZmOlhSZXNvbHV0aW9uPSI5Ni4wIgogICB0aWZmOllSZXNvbHV0aW9uPSI5Ni4wIgogICB4bXA6TW9kaWZ5RGF0ZT0iMjAyMS0wMy0xMVQyMToyMjozMC0wNjowMCIKICAgeG1wOk1ldGFkYXRhRGF0ZT0iMjAyMS0wMy0xMVQyMToyMjozMC0wNjowMCI+CiAgIDx4bXBNTTpIaXN0b3J5PgogICAgPHJkZjpTZXE+CiAgICAgPHJkZjpsaQogICAgICBzdEV2dDphY3Rpb249InByb2R1Y2VkIgogICAgICBzdEV2dDpzb2Z0d2FyZUFnZW50PSJBZmZpbml0eSBQaG90byAxLjcuMSIKICAgICAgc3RFdnQ6d2hlbj0iMjAyMS0wMy0xMVQyMToyMjozMC0wNjowMCIvPgogICAgPC9yZGY6U2VxPgogICA8L3htcE1NOkhpc3Rvcnk+CiAgPC9yZGY6RGVzY3JpcHRpb24+CiA8L3JkZjpSREY+CjwveDp4bXBtZXRhPgo8P3hwYWNrZXQgZW5kPSJyIj8+NRFFrAAAAYFpQ0NQc1JHQiBJRUM2MTk2Ni0yLjEAACiRdZG/S0JRFMc/amGUYZBDQ4NENVmUgdTSoJQF1WAG/Vr05Y9A7fGeEdIatAoFUUu/hvoLag2ag6AogmgLmotaSl7n+QQl8l7OOZ/7vfcc7j0X7NGMktUbBiCby2uRcNA7v7Dodb7iwCXmwRNTdHV6djxK3fH1gM2Md31mrfrn/h0tKwldAVuT8KiiannhCeGpjbxq8q6wR0nHVoTPhX2aXFD43tTjFr+ZnLL4x2QtGgmBvU3Ym6rheA0raS0rLC+nO5tZVyr3MV/iSuTmZiV2iXWiEyFMEC+TjBEiwCAj4gP04adfVtTJHyjnz7AmuYp4lQIaq6RIk8cn6rpUT0hMip6QmaFg9v9vX/XkkN+q7gpC44thfPSAcwdKRcP4PjaM0gk4nuEqV81fO4LhT9GLVa37ENxbcHFd1eJ7cLkNHU9qTIuVJYeYPZmE9zNoXYD2W2hesnpW2ef0EaKb8lU3sH8AvXLevfwLEU5nv19tQRgAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAJOSURBVHic7ZtRksMgCIaTPOcI3v9MPYBHyHv2obOZTlIVFeSHyltnm38QCehXdo0xnkulHcex7Pue/OxJZ20JUE7Um86W+wKHM1w6IYRVw59sBqHtagihO+Nr/Xlk0GeE930nRTzlBIfOZ+bEGE9KJnH68wjQ/eHWxXHp3IPSGqRWf64A5R6uWRyXTi4oNUHq9ecKUOlh6uK4dEpBoQap159H0UM7m9wLc2uhbvVn1qCCJXdjtvi3JQ+K1AiXdpOqU/oONXNKOrX+dO2K1q6O1Nl6DnD34tnrzP9nJJ3NYmcZqfP1oJizUnBqDnC5RdUcTCV1tm9/TBklOJRMoiyK4s8InfX1ep3zNUvrzBpU0Olu095bfRdRpATHOpk0RRQ1ri3wRFGbTMLf5rWpACxRRCGTsEQRhUzCE0VtMjlrUMHMEEUtMtlNFLkJnrROLZnsuiagZQcUUUQngapEEa1DQRFFKySQS6eKKFoigVw6zUTRwuuhRhTRFwVFFJFbNIdO8qCoNROIppPNIO+8mWKPDNKeCUTTeQRIex4HTecKEMpMIJrOFSCUmUA0nUcR/qVfTSk6swYVLJkds8W/LXlQ1JoJ7NXhnpl0RRQlst4NUZSamXRxm5fsvOaJovTMpGmiOGJm0g1RlHrNZg0q+OOOKHK3evH/eh5JJiVmJofMKFq+tojNKHohk2LzQV6oAPuMojcyyT6j6I1Mis0oeiGTswYVTHxG0XKLX5YBM4pWyaRLoiih44YoSum4uM1L6pgnitI6poniCB03RFFK5w8yFS9yPecAUAAAAABJRU5ErkJggg==" }}
|
||||||
|
{{ $bgdark := "iVBORw0KGgoAAAANSUhEUgAAAEgAAABICAYAAABV7bNHAAAEGGlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4KPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iWE1QIENvcmUgNS41LjAiPgogPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgeG1sbnM6ZXhpZj0iaHR0cDovL25zLmFkb2JlLmNvbS9leGlmLzEuMC8iCiAgICB4bWxuczp0aWZmPSJodHRwOi8vbnMuYWRvYmUuY29tL3RpZmYvMS4wLyIKICAgIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyIKICAgIHhtbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIgogICAgeG1sbnM6c3RFdnQ9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZUV2ZW50IyIKICAgZXhpZjpQaXhlbFhEaW1lbnNpb249IjcyIgogICBleGlmOlBpeGVsWURpbWVuc2lvbj0iNzIiCiAgIHRpZmY6SW1hZ2VXaWR0aD0iNzIiCiAgIHRpZmY6SW1hZ2VMZW5ndGg9IjcyIgogICB0aWZmOlJlc29sdXRpb25Vbml0PSIyIgogICB0aWZmOlhSZXNvbHV0aW9uPSI5Ni4wIgogICB0aWZmOllSZXNvbHV0aW9uPSI5Ni4wIgogICB4bXA6TW9kaWZ5RGF0ZT0iMjAyMS0wMy0xMVQyMToyMzoxNS0wNjowMCIKICAgeG1wOk1ldGFkYXRhRGF0ZT0iMjAyMS0wMy0xMVQyMToyMzoxNS0wNjowMCI+CiAgIDx4bXBNTTpIaXN0b3J5PgogICAgPHJkZjpTZXE+CiAgICAgPHJkZjpsaQogICAgICBzdEV2dDphY3Rpb249InByb2R1Y2VkIgogICAgICBzdEV2dDpzb2Z0d2FyZUFnZW50PSJBZmZpbml0eSBQaG90byAxLjcuMSIKICAgICAgc3RFdnQ6d2hlbj0iMjAyMS0wMy0xMVQyMToyMzoxNS0wNjowMCIvPgogICAgPC9yZGY6U2VxPgogICA8L3htcE1NOkhpc3Rvcnk+CiAgPC9yZGY6RGVzY3JpcHRpb24+CiA8L3JkZjpSREY+CjwveDp4bXBtZXRhPgo8P3hwYWNrZXQgZW5kPSJyIj8+87tjqAAAAYFpQ0NQc1JHQiBJRUM2MTk2Ni0yLjEAACiRdZG/S0JRFMc/amGUYZBDQ4NENVmUgdTSoJQF1WAG/Vr05Y9A7fGeEdIatAoFUUu/hvoLag2ag6AogmgLmotaSl7n+QQl8l7OOZ/7vfcc7j0X7NGMktUbBiCby2uRcNA7v7Dodb7iwCXmwRNTdHV6djxK3fH1gM2Md31mrfrn/h0tKwldAVuT8KiiannhCeGpjbxq8q6wR0nHVoTPhX2aXFD43tTjFr+ZnLL4x2QtGgmBvU3Ym6rheA0raS0rLC+nO5tZVyr3MV/iSuTmZiV2iXWiEyFMEC+TjBEiwCAj4gP04adfVtTJHyjnz7AmuYp4lQIaq6RIk8cn6rpUT0hMip6QmaFg9v9vX/XkkN+q7gpC44thfPSAcwdKRcP4PjaM0gk4nuEqV81fO4LhT9GLVa37ENxbcHFd1eJ7cLkNHU9qTIuVJYeYPZmE9zNoXYD2W2hesnpW2ef0EaKb8lU3sH8AvXLevfwLEU5nv19tQRgAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAJSSURBVHic7ZvBbsMgDIaTHKbtnNO0vf/bcW7VS3uoFlWhgAEb//bwrVrzyxjHhq/euu/7fam0z4+v5Xq7JD970llbApQT9aaz5b7A4QyXTghh1fAnm0FouxpC6M74Wn+iDHqN8PV2IUU85QSHzmvm7Pt+p2QSpz9RgM4Pty6OS+cclNYgtfpzBCj3cM3iuHRyQakJUq8/R4BKD1MXx6VTCgo1SL3+REUP7WxyLsythbrVn1mDCpbcjdnin5Y8KFIjXNpNqk7pO9TMKenU+tO1K1q7OlJn6znAnYtnrzN/n5F0NoudZaTO24NizkrBqTnA5RZVczCV1Nne/TFllOBQMomyKIo/I3TWn+/f+3zN0jqzBhV0utu091bfRRQpwbFOJk0RRY1rCzxR1CaT8Ld5bSoASxRRyCQsUUQhk/BEUZtMzhpUMDNEUYtMdhNFboInrVNLJruuCWjZAUUU0UmgKlFE61BQRNEKCeTSqSKKlkggl04zUbTweqgRRfRFQRFF5BbNoZM8KGrNBKLpZDPIO2+mWJRB2jOBaDpRgLTncdB0jgChzASi6RwBQpkJRNOJivB/+tWUojNrUMGS2TFb/NOSB0WtmcBeHe6ZSVdEUSLr3RBFqZlJF7d5yc5rnihKz0yaJoojZibdEEWp12zWoII/7ogid6sX/6/nkWRSYmZyyIyi5WuL2IyiFzIpNh/khQqwzyh6I5PsM4reyKTYjKIXMjlrUMHEZxQtt/hlGTCjaJVMuiSKEjpuiKKUjovbvKSOeaIorWOaKI7QcUMUpXQe+31Pc6xeN0AAAAAASUVORK5CYII=" }}
|
||||||
|
<style type="text/css">
|
||||||
|
body {
|
||||||
|
{{ if .BackgroundImage.Url }}
|
||||||
|
background-image: url("{{ .BackgroundImage.Url }}?v={{ .BackgroundImage.Size }}");
|
||||||
|
background-attachment: fixed;
|
||||||
|
{{ with .BackgroundImage.Size }}
|
||||||
|
background-size: "{{ . }}";
|
||||||
|
{{ end }}
|
||||||
|
{{ else }}
|
||||||
|
background-color: #{{ or .ProjectColor "999999" }};
|
||||||
|
{{ if eq .Theme "dark" }}
|
||||||
|
background-image: url('data:image/png;{{ $bgdark }}');
|
||||||
|
{{ else }}
|
||||||
|
background-image: url('data:image/png;{{ $bglight }}');
|
||||||
|
{{ end }}
|
||||||
|
{{ end }}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
{{ block "extrahead" . }}{{ end }}
|
||||||
|
<link rel="stylesheet" href="{{ statictheme .Theme "theme.css" }}" />
|
||||||
|
<link rel="stylesheet" href="{{ url "assets/project.css" }}" />
|
||||||
|
<link rel="apple-touch-icon" sizes="57x57" href="{{ static "apple-icon-57x57.png" }}">
|
||||||
|
<link rel="apple-touch-icon" sizes="60x60" href="{{ static "apple-icon-60x60.png" }}">
|
||||||
|
<link rel="apple-touch-icon" sizes="72x72" href="{{ static "apple-icon-72x72.png" }}">
|
||||||
|
<link rel="apple-touch-icon" sizes="76x76" href="{{ static "apple-icon-76x76.png" }}">
|
||||||
|
<link rel="apple-touch-icon" sizes="114x114" href="{{ static "apple-icon-114x114.png" }}">
|
||||||
|
<link rel="apple-touch-icon" sizes="120x120" href="{{ static "apple-icon-120x120.png" }}">
|
||||||
|
<link rel="apple-touch-icon" sizes="144x144" href="{{ static "apple-icon-144x144.png" }}">
|
||||||
|
<link rel="apple-touch-icon" sizes="152x152" href="{{ static "apple-icon-152x152.png" }}">
|
||||||
|
<link rel="apple-touch-icon" sizes="180x180" href="{{ static "apple-icon-180x180.png" }}">
|
||||||
|
<link rel="icon" type="image/png" sizes="192x192" href="{{ static "android-icon-192x192.png" }}">
|
||||||
|
<link rel="icon" type="image/png" sizes="16x16" href="{{ static "favicon-16x16.png" }}">
|
||||||
|
<link rel="icon" type="image/png" sizes="32x32" href="{{ static "favicon-32x32.png" }}">
|
||||||
|
<link rel="icon" type="image/png" sizes="96x96" href="{{ static "favicon-96x96.png" }}">
|
||||||
|
<link rel="manifest" href="{{ static "manifest.json" }}">
|
||||||
|
<meta name="msapplication-TileColor" content="#ffffff">
|
||||||
|
<meta name="msapplication-TileImage" content="{{ static "ms-icon-144x144.png" }}">
|
||||||
|
<meta name="theme-color" content="#ffffff">
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body class="{{ join " " .BodyClasses }}">
|
||||||
|
<div class="content mw-site ph3-m ph4-l">
|
||||||
|
{{ template "header.html" }}
|
||||||
|
based
|
||||||
|
{{ template "footer.html" }}
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
|
@ -0,0 +1,13 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<title>{{ block "title" . }}Handmade Network{{ end }}</title>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
{{ block "content" . }}{{ end }}
|
||||||
|
{{ template "footer.html" . }}
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
|
@ -0,0 +1,128 @@
|
||||||
|
{{ $themeDim := eq .Theme "dark" | ternary (darken .Color 0.5) (brighten .Color 0.2) }}
|
||||||
|
{{ $themeDimmer := eq .Theme "dark" | ternary (darken .Color 0.65) (brighten .Color 0.4) }}
|
||||||
|
{{ $themeDimmest := eq .Theme "dark" | ternary (darken .Color 0.8) (brighten .Color 0.6) }}
|
||||||
|
|
||||||
|
{{ $linkColor := eq .Theme "dark" | ternary (brighten .Color 0.1) (darken .Color 0.2) }}
|
||||||
|
{{ $linkHoverColor := eq .Theme "dark" | ternary (brighten .Color 0.2) (darken .Color 0.1) }}
|
||||||
|
|
||||||
|
:root {
|
||||||
|
--theme-color: #{{ .Color }};
|
||||||
|
--theme-color-dim: #{{ $themeDim }};
|
||||||
|
--theme-color-dimmer: #{{ $themeDimmer }};
|
||||||
|
--theme-color-dimmest: #{{ $themeDimmest }};
|
||||||
|
|
||||||
|
--link-color: #{{ $linkColor }};
|
||||||
|
--link-color-hover: #{{ $linkHoverColor }};
|
||||||
|
}
|
||||||
|
|
||||||
|
.accent {
|
||||||
|
background-color: #{{ $themeDim }};
|
||||||
|
background-color: var(--theme-dim);
|
||||||
|
}
|
||||||
|
.user-bar {
|
||||||
|
border-bottom-color: #{{ $themeDim }};
|
||||||
|
border-bottom-color: var(--theme-dim);
|
||||||
|
}
|
||||||
|
header .content-title .subtitle {
|
||||||
|
border-top-color: #{{ $themeDim }};
|
||||||
|
border-top-color: var(--theme-dim);
|
||||||
|
}
|
||||||
|
|
||||||
|
a, .thread:before, button, .button, input[type=button], input[type=submit] {
|
||||||
|
color: #{{ $linkColor }};
|
||||||
|
color: var(--link-color);
|
||||||
|
}
|
||||||
|
a:hover, button:hover, .button:hover, input[type=button]:hover, input[type=submit]:hover {
|
||||||
|
color: #{{ $linkHoverColor }};
|
||||||
|
color: var(--link-hover-color);
|
||||||
|
}
|
||||||
|
.unread .avatar-icon {
|
||||||
|
border: 2px solid #{{ $linkColor }};
|
||||||
|
border: 2px solid var(--link-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
TODO: Manually apply sensible tachyons classes to the elements styled below, then delete
|
||||||
|
all of this CSS.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* {% if theme == "dark" %}
|
||||||
|
#search_form_input_homepage { color: #{% rgb_accent accent 0.65 %}; }
|
||||||
|
#search_form_input_homepage::-webkit-input-placeholder { color: #{% rgb_accent accent 0.65 %}; }
|
||||||
|
#search_form_input_homepage:-moz-placeholder { color: #{% rgb_accent accent 0.65 %}; }
|
||||||
|
#search_form_input_homepage::-moz-placeholder { color: #{% rgb_accent accent 0.65 %}; }
|
||||||
|
#search_form_input_homepage:-ms-input-placeholder { color: #{% rgb_accent accent 0.65 %}; }
|
||||||
|
{% else %}
|
||||||
|
#search_form_input_homepage { color: #{% rgb_accent accent 0.25 %}; }
|
||||||
|
#search_form_input_homepage::-webkit-input-placeholder { color: #{% rgb_accent accent 0.25 %}; }
|
||||||
|
#search_form_input_homepage:-moz-placeholder { color: #{% rgb_accent accent 0.25 %}; }
|
||||||
|
#search_form_input_homepage::-moz-placeholder { color: #{% rgb_accent accent 0.25 %}; }
|
||||||
|
#search_form_input_homepage:-ms-input-placeholder { color: #{% rgb_accent accent 0.25 %}; }
|
||||||
|
{% endif %} */
|
||||||
|
|
||||||
|
/* {% if theme == "dark" %}
|
||||||
|
header .menu-bar .logo { background-color: #{% rgb_accent accent 0.23 %}; }
|
||||||
|
header .menu-bar .logo:hover { background-color: #{% rgb_accent accent 0.27 %}; }
|
||||||
|
header { border-bottom-color:#{% rgb_accent accent 0.33 %}; }
|
||||||
|
.post .action.button { border-bottom-color:#{% rgb_accent accent 0.33 %}; }
|
||||||
|
:root {
|
||||||
|
--input-lite-border: #{% rgb_accent accent 0.33 %};
|
||||||
|
}
|
||||||
|
|
||||||
|
header #unfold-btn-fx { background-color: #{% rgb_accent accent 0.23 %}; }
|
||||||
|
header #unfold-btn-fx:hover { background-color: #{% rgb_accent accent 0.21 %}; }
|
||||||
|
|
||||||
|
.forum .thread:nth-of-type(odd) { background-color:#{% rgb_accent accent 0.14 False 0.03%}; }
|
||||||
|
.blog .post:nth-of-type(even) { background-color:#{% rgb_accent accent 0.14 False 0.03 %}; }
|
||||||
|
{% else %}
|
||||||
|
header .menu-bar .logo { background-color: #{% rgb_accent accent 0.25 True %}; }
|
||||||
|
header .menu-bar .logo:hover { background-color: #{% rgb_accent accent 0.28 True %}; }
|
||||||
|
header { border-bottom-color:#{% rgb_accent accent 0.18 %}; }
|
||||||
|
.post .action.button { border-bottom-color:#{% rgb_accent accent 0.25 True %}; }
|
||||||
|
:root {
|
||||||
|
--input-lite-border: #{% rgb_accent accent 0.25 True %};
|
||||||
|
}
|
||||||
|
|
||||||
|
header #unfold-btn-fx { background-color: #{% rgb_accent accent 0.20 %}; }
|
||||||
|
header #unfold-btn-fx:hover { background-color: #{% rgb_accent accent 0.16 %}; }
|
||||||
|
|
||||||
|
.forum .thread:nth-of-type(odd) { background-color:#{% rgb_accent accent 0.94 False 0.2 %}; }
|
||||||
|
.blog .post:nth-of-type(even) { background-color:#{% rgb_accent accent 0.94 False 0.2 %}; }
|
||||||
|
{% endif %} */
|
||||||
|
|
||||||
|
:root {
|
||||||
|
--background-even-background: #{{ eq .Theme "dark" | ternary (darken .Color 0.8) (brighten .Color 0.9) }};
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Assets */
|
||||||
|
|
||||||
|
header .menu-bar .hmdev-logo {
|
||||||
|
background-image:url("{{ static "logo_nounder.svg" }}");
|
||||||
|
}
|
||||||
|
header .menu-bar .hmdev-logo .underscore {
|
||||||
|
background-image:url("{{ static "logo_underscore.svg" }}");
|
||||||
|
}
|
||||||
|
|
||||||
|
header .menu-bar .hmdev-logo.project {
|
||||||
|
background-image:url("{{ static "logo_net.svg" }}");
|
||||||
|
}
|
||||||
|
|
||||||
|
.links .thing#projects {
|
||||||
|
background-image:url("{{ statictheme .Theme "project_thing.svg" }}");
|
||||||
|
}
|
||||||
|
|
||||||
|
.links .thing#discussion {
|
||||||
|
background-image:url("{{ statictheme .Theme "discuss_thing.svg" }}");
|
||||||
|
}
|
||||||
|
|
||||||
|
.links .thing#blogs {
|
||||||
|
background-image:url("{{ statictheme .Theme "blog_thing.svg" }}");
|
||||||
|
}
|
||||||
|
|
||||||
|
.half.light {
|
||||||
|
background-image:url("{{ statictheme "light" "accent_top_a.svg" }}");
|
||||||
|
}
|
||||||
|
|
||||||
|
.half.dark {
|
||||||
|
background-image:url("{{ statictheme "dark" "accent_top_a.svg" }}");
|
||||||
|
}
|
|
@ -0,0 +1,104 @@
|
||||||
|
package templates
|
||||||
|
|
||||||
|
import (
|
||||||
|
"embed"
|
||||||
|
"fmt"
|
||||||
|
"html/template"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"git.handmade.network/hmn/hmn/src/logging"
|
||||||
|
"github.com/Masterminds/sprig"
|
||||||
|
"github.com/teacat/noire"
|
||||||
|
)
|
||||||
|
|
||||||
|
//go:embed src
|
||||||
|
var templateFs embed.FS
|
||||||
|
var Templates map[string]*template.Template
|
||||||
|
|
||||||
|
var cachebust string
|
||||||
|
|
||||||
|
func Init() {
|
||||||
|
cachebust = fmt.Sprint(time.Now().Unix())
|
||||||
|
|
||||||
|
Templates = make(map[string]*template.Template)
|
||||||
|
|
||||||
|
files, _ := templateFs.ReadDir("src")
|
||||||
|
for _, f := range files {
|
||||||
|
if strings.HasSuffix(f.Name(), ".html") {
|
||||||
|
t := template.New(f.Name())
|
||||||
|
t = t.Funcs(sprig.FuncMap())
|
||||||
|
t = t.Funcs(HMNTemplateFuncs)
|
||||||
|
t, err := t.ParseFS(templateFs, "src/layouts/*.html", "src/include/*.html", "src/"+f.Name())
|
||||||
|
if err != nil {
|
||||||
|
logging.Fatal().Str("filename", f.Name()).Err(err).Msg("failed to parse template")
|
||||||
|
}
|
||||||
|
|
||||||
|
Templates[f.Name()] = t
|
||||||
|
} else if strings.HasSuffix(f.Name(), ".css") {
|
||||||
|
t := template.New(f.Name())
|
||||||
|
t = t.Funcs(sprig.FuncMap())
|
||||||
|
t = t.Funcs(HMNTemplateFuncs)
|
||||||
|
t, err := t.ParseFS(templateFs, "src/"+f.Name())
|
||||||
|
if err != nil {
|
||||||
|
logging.Fatal().Str("filename", f.Name()).Err(err).Msg("failed to parse template")
|
||||||
|
}
|
||||||
|
|
||||||
|
Templates[f.Name()] = t
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for name, t := range Templates {
|
||||||
|
fmt.Printf("%s: %v\n", name, names(t.Templates()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func names(ts []*template.Template) []string {
|
||||||
|
result := make([]string, len(ts))
|
||||||
|
for i, t := range ts {
|
||||||
|
result[i] = t.Name()
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
var HMNTemplateFuncs = template.FuncMap{
|
||||||
|
"brighten": func(hexColor string, amount float64) (string, error) {
|
||||||
|
if len(hexColor) < 6 {
|
||||||
|
return "", fmt.Errorf("couldn't brighten invalid hex color: %v", hexColor)
|
||||||
|
}
|
||||||
|
return noire.NewHex(hexColor).Tint(amount).Hex(), nil
|
||||||
|
},
|
||||||
|
"cachebust": func() string {
|
||||||
|
return cachebust
|
||||||
|
},
|
||||||
|
"darken": func(hexColor string, amount float64) (string, error) {
|
||||||
|
if len(hexColor) < 6 {
|
||||||
|
return "", fmt.Errorf("couldn't darken invalid hex color: %v", hexColor)
|
||||||
|
}
|
||||||
|
return noire.NewHex(hexColor).Shade(amount).Hex(), nil
|
||||||
|
},
|
||||||
|
// TODO: Actually put paths in here, duh
|
||||||
|
"static": func(filepath string) string {
|
||||||
|
return fmt.Sprintf("A static file at %v, busted with %v", filepath, cachebust)
|
||||||
|
},
|
||||||
|
"staticnobust": func(filepath string) string {
|
||||||
|
return fmt.Sprintf("A static file at %v", filepath)
|
||||||
|
},
|
||||||
|
"statictheme": func(theme string, filepath string) string {
|
||||||
|
return fmt.Sprintf("A static file for the current theme at %v, busted with %v", filepath, cachebust)
|
||||||
|
},
|
||||||
|
"staticthemenobust": func(theme string, filepath string) string {
|
||||||
|
return fmt.Sprintf("A static file for the current theme at %v", filepath)
|
||||||
|
},
|
||||||
|
"url": func(url string) string {
|
||||||
|
return "/" + url
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
type ErrInvalidHexColor struct {
|
||||||
|
color string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e ErrInvalidHexColor) Error() string {
|
||||||
|
return fmt.Sprintf("invalid hex color: %s", e.color)
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
package templates
|
||||||
|
|
||||||
|
type BaseData struct {
|
||||||
|
Title string
|
||||||
|
CanonicalLink string
|
||||||
|
OpenGraphItems []OpenGraphItem
|
||||||
|
BackgroundImage BackgroundImage
|
||||||
|
ProjectColor string
|
||||||
|
Theme string
|
||||||
|
BodyClasses []string
|
||||||
|
}
|
||||||
|
|
||||||
|
type OpenGraphItem struct {
|
||||||
|
Property string
|
||||||
|
Name string
|
||||||
|
Value string
|
||||||
|
}
|
||||||
|
|
||||||
|
type BackgroundImage struct {
|
||||||
|
Url string
|
||||||
|
Size string // A valid CSS background-size value
|
||||||
|
}
|
|
@ -0,0 +1,88 @@
|
||||||
|
package website
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
_ "embed"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"git.handmade.network/hmn/hmn/src/logging"
|
||||||
|
"git.handmade.network/hmn/hmn/src/templates"
|
||||||
|
_ "git.handmade.network/hmn/hmn/src/templates"
|
||||||
|
"github.com/jackc/pgx/v4/pgxpool"
|
||||||
|
"github.com/julienschmidt/httprouter"
|
||||||
|
)
|
||||||
|
|
||||||
|
type websiteRoutes struct {
|
||||||
|
*httprouter.Router
|
||||||
|
|
||||||
|
conn *pgxpool.Pool
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewWebsiteRoutes(conn *pgxpool.Pool) http.Handler {
|
||||||
|
routes := &websiteRoutes{
|
||||||
|
Router: httprouter.New(),
|
||||||
|
conn: conn,
|
||||||
|
}
|
||||||
|
|
||||||
|
routes.GET("/", routes.Index)
|
||||||
|
routes.GET("/project/:id", routes.Project)
|
||||||
|
routes.GET("/assets/project.css", routes.ProjectCSS)
|
||||||
|
|
||||||
|
return routes
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
TODO: Make a custom context thing so that routes won't directly use a response writer.
|
||||||
|
|
||||||
|
This should store up a body, desired headers, status codes, etc. Doing this allows us to
|
||||||
|
make middleware that can write headers after an aborted request.
|
||||||
|
|
||||||
|
This context should also provide a sub-logger with request fields so we can easily see
|
||||||
|
which URLs are having problems.
|
||||||
|
*/
|
||||||
|
|
||||||
|
func (s *websiteRoutes) Index(rw http.ResponseWriter, r *http.Request, p httprouter.Params) {
|
||||||
|
err := templates.Templates["index.html"].Execute(rw, templates.BaseData{
|
||||||
|
ProjectColor: "cd4e31",
|
||||||
|
Theme: "dark",
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *websiteRoutes) Project(rw http.ResponseWriter, r *http.Request, p httprouter.Params) {
|
||||||
|
id := p.ByName("id")
|
||||||
|
row := s.conn.QueryRow(context.Background(), "SELECT name FROM handmade_project WHERE id = $1", p.ByName("id"))
|
||||||
|
var name string
|
||||||
|
err := row.Scan(&name)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
rw.Write([]byte(fmt.Sprintf("(%s) %s\n", id, name)))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *websiteRoutes) ProjectCSS(rw http.ResponseWriter, r *http.Request, p httprouter.Params) {
|
||||||
|
color := r.URL.Query().Get("color")
|
||||||
|
if color == "" {
|
||||||
|
rw.WriteHeader(http.StatusBadRequest)
|
||||||
|
rw.Write([]byte("You must provide a 'color' parameter.\n"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
templateData := struct {
|
||||||
|
Color string
|
||||||
|
Theme string
|
||||||
|
}{
|
||||||
|
Color: color,
|
||||||
|
Theme: "dark",
|
||||||
|
}
|
||||||
|
|
||||||
|
err := templates.Templates["project.css"].Execute(rw, templateData)
|
||||||
|
if err != nil {
|
||||||
|
logging.Error().Err(err).Msg("failed to generate project CSS")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,7 +3,6 @@ package website
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
|
@ -12,6 +11,7 @@ import (
|
||||||
"git.handmade.network/hmn/hmn/src/config"
|
"git.handmade.network/hmn/hmn/src/config"
|
||||||
"git.handmade.network/hmn/hmn/src/db"
|
"git.handmade.network/hmn/hmn/src/db"
|
||||||
"git.handmade.network/hmn/hmn/src/logging"
|
"git.handmade.network/hmn/hmn/src/logging"
|
||||||
|
"git.handmade.network/hmn/hmn/src/templates"
|
||||||
"github.com/julienschmidt/httprouter"
|
"github.com/julienschmidt/httprouter"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
@ -19,31 +19,17 @@ import (
|
||||||
var WebsiteCommand = &cobra.Command{
|
var WebsiteCommand = &cobra.Command{
|
||||||
Short: "Run the HMN website",
|
Short: "Run the HMN website",
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
|
templates.Init()
|
||||||
|
|
||||||
defer logging.LogPanics()
|
defer logging.LogPanics()
|
||||||
|
|
||||||
logging.Info().Msg("Hello, HMN!")
|
logging.Info().Msg("Hello, HMN!")
|
||||||
|
|
||||||
conn := db.NewConnPool(4, 8)
|
conn := db.NewConnPool(4, 8)
|
||||||
|
|
||||||
router := httprouter.New()
|
|
||||||
router.GET("/", WithRequestLogger(func(rw http.ResponseWriter, r *http.Request, p httprouter.Params) {
|
|
||||||
rw.Write([]byte(fmt.Sprintf("Hello, HMN! The time is: %v\n", time.Now())))
|
|
||||||
}))
|
|
||||||
router.GET("/project/:id", func(rw http.ResponseWriter, r *http.Request, p httprouter.Params) {
|
|
||||||
id := p.ByName("id")
|
|
||||||
row := conn.QueryRow(context.Background(), "SELECT name FROM handmade_project WHERE id = $1", p.ByName("id"))
|
|
||||||
var name string
|
|
||||||
err := row.Scan(&name)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
rw.Write([]byte(fmt.Sprintf("(%s) %s\n", id, name)))
|
|
||||||
})
|
|
||||||
|
|
||||||
server := http.Server{
|
server := http.Server{
|
||||||
Addr: config.Config.Addr,
|
Addr: config.Config.Addr,
|
||||||
Handler: router,
|
Handler: NewWebsiteRoutes(conn),
|
||||||
}
|
}
|
||||||
|
|
||||||
signals := make(chan os.Signal, 1)
|
signals := make(chan os.Signal, 1)
|
||||||
|
@ -67,7 +53,7 @@ var WebsiteCommand = &cobra.Command{
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
func WithRequestLogger(h httprouter.Handle) httprouter.Handle {
|
func withRequestLogger(h httprouter.Handle) httprouter.Handle {
|
||||||
return func(rw http.ResponseWriter, r *http.Request, p httprouter.Params) {
|
return func(rw http.ResponseWriter, r *http.Request, p httprouter.Params) {
|
||||||
defer logging.LogPanics()
|
defer logging.LogPanics()
|
||||||
|
|
||||||
|
@ -80,3 +66,5 @@ func WithRequestLogger(h httprouter.Handle) httprouter.Handle {
|
||||||
h(rw, r, p)
|
h(rw, r, p)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// func handleRequestResults
|
||||||
|
|
Loading…
Reference in New Issue