Compare commits

...

5 Commits

Author SHA1 Message Date
cel 🌸 29165c4c93 add bunny.garden assets 2024-02-20 00:40:51 +00:00
cel 🌸 f4ff8fe6eb fix routes 2024-02-20 00:24:38 +00:00
cel 🌸 ac0983a896 support categories 2024-02-19 23:49:34 +00:00
cel 🌸 3c1b8007b6 support categories at index 2024-02-19 22:23:39 +00:00
dependabot[bot] bdfc973207
deps: bump go-git
Bumps [github.com/go-git/go-git/v5](https://github.com/go-git/go-git) from 5.6.1 to 5.11.0.
- [Release notes](https://github.com/go-git/go-git/releases)
- [Commits](https://github.com/go-git/go-git/compare/v5.6.1...v5.11.0)

---
updated-dependencies:
- dependency-name: github.com/go-git/go-git/v5
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-12-27 17:20:48 +02:00
17 changed files with 588 additions and 396 deletions

View File

@ -1,5 +1,5 @@
repo:
scanPath: /var/www/git
scanPath: ./repositories
readme:
- readme
- README
@ -12,9 +12,9 @@ dirs:
templates: ./templates
static: ./static
meta:
title: git good
description: i think it's a skill issue
title: the bunny garden
description: git repos!!!
server:
name: git.icyphox.sh
name: bunny.garden
host: 127.0.0.1
port: 5555

29
go.mod
View File

@ -6,34 +6,35 @@ require (
github.com/alexedwards/flow v0.0.0-20220806114457-cf11be9e0e03
github.com/bluekeyes/go-gitdiff v0.7.0
github.com/dustin/go-humanize v1.0.1
github.com/go-git/go-billy/v5 v5.4.1
github.com/go-git/go-git/v5 v5.6.1
github.com/go-git/go-billy/v5 v5.5.0
github.com/go-git/go-git/v5 v5.11.0
github.com/microcosm-cc/bluemonday v1.0.23
github.com/russross/blackfriday/v2 v2.1.0
golang.org/x/sys v0.7.0
golang.org/x/sys v0.15.0
gopkg.in/yaml.v3 v3.0.1
)
require (
github.com/Microsoft/go-winio v0.6.0 // indirect
github.com/ProtonMail/go-crypto v0.0.0-20230331115716-d34776aa93ec // indirect
github.com/acomagu/bufpipe v1.0.4 // indirect
dario.cat/mergo v1.0.0 // indirect
github.com/Microsoft/go-winio v0.6.1 // indirect
github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371 // indirect
github.com/aymerick/douceur v0.2.0 // indirect
github.com/cloudflare/circl v1.3.2 // indirect
github.com/cloudflare/circl v1.3.3 // indirect
github.com/cyphar/filepath-securejoin v0.2.4 // indirect
github.com/emirpasic/gods v1.18.1 // indirect
github.com/go-git/gcfg v1.5.0 // indirect
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/gorilla/css v1.0.0 // indirect
github.com/imdario/mergo v0.3.15 // indirect
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
github.com/kevinburke/ssh_config v1.2.0 // indirect
github.com/pjbgf/sha1cd v0.3.0 // indirect
github.com/sergi/go-diff v1.3.1 // indirect
github.com/skeema/knownhosts v1.1.0 // indirect
github.com/skeema/knownhosts v1.2.1 // indirect
github.com/xanzy/ssh-agent v0.3.3 // indirect
golang.org/x/crypto v0.8.0 // indirect
golang.org/x/mod v0.10.0 // indirect
golang.org/x/net v0.9.0 // indirect
golang.org/x/tools v0.8.0 // indirect
golang.org/x/crypto v0.16.0 // indirect
golang.org/x/mod v0.12.0 // indirect
golang.org/x/net v0.19.0 // indirect
golang.org/x/tools v0.13.0 // indirect
gopkg.in/warnings.v0 v0.1.2 // indirect
)

122
go.sum
View File

@ -1,148 +1,122 @@
dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk=
dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk=
github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY=
github.com/Microsoft/go-winio v0.6.0 h1:slsWYD/zyx7lCXoZVlvQrj0hPTM1HI4+v1sIda2yDvg=
github.com/Microsoft/go-winio v0.6.0/go.mod h1:cTAf44im0RAYeL23bpB+fzCyDH2MJiz2BO69KH/soAE=
github.com/ProtonMail/go-crypto v0.0.0-20230217124315-7d5c6f04bbb8/go.mod h1:I0gYDMZ6Z5GRU7l58bNFSkPTFN6Yl12dsUlAZ8xy98g=
github.com/ProtonMail/go-crypto v0.0.0-20230331115716-d34776aa93ec h1:eQusauqzE1cAFR5hGnwkuSmFxKoy3+j9/cVaDeYfjjs=
github.com/ProtonMail/go-crypto v0.0.0-20230331115716-d34776aa93ec/go.mod h1:8TI4H3IbrackdNgv+92dI+rhpCaLqM0IfpgCgenFvRE=
github.com/acomagu/bufpipe v1.0.4 h1:e3H4WUzM3npvo5uv95QuJM3cQspFNtFBzvJ2oNjKIDQ=
github.com/acomagu/bufpipe v1.0.4/go.mod h1:mxdxdup/WdsKVreO5GpW4+M/1CE2sMG4jeGJ2sYmHc4=
github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow=
github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM=
github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371 h1:kkhsdkhsCvIsutKu5zLMgWtgh9YxGCNAw8Ad8hjwfYg=
github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0=
github.com/alexedwards/flow v0.0.0-20220806114457-cf11be9e0e03 h1:r07xZN3ENBWdxGuU/feCsnpsgHJ7+3uLm7cq9S0sqoI=
github.com/alexedwards/flow v0.0.0-20220806114457-cf11be9e0e03/go.mod h1:1rjOQiOqQlmMdUMuvlJFjldqTnE/tQULE7qPIu4aq3U=
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/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk=
github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4=
github.com/bluekeyes/go-gitdiff v0.7.0 h1:w4SrRFcufU0/tEpWx3VurDBAnWfpxsmwS7yWr14meQk=
github.com/bluekeyes/go-gitdiff v0.7.0/go.mod h1:QpfYYO1E0fTVHVZAZKiRjtSGY9823iCdvGXBcEzHGbM=
github.com/bwesterb/go-ristretto v1.2.0/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0=
github.com/cloudflare/circl v1.1.0/go.mod h1:prBCrKB9DV4poKZY1l9zBXg2QJY7mvgRvtMxxK7fi4I=
github.com/cloudflare/circl v1.3.2 h1:VWp8dY3yH69fdM7lM6A1+NhhVoDu9vqK0jOgmkQHFWk=
github.com/cloudflare/circl v1.3.2/go.mod h1:+CauBF6R70Jqcyl8N2hC8pAXYbWkGIezuSbuGLtRhnw=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0=
github.com/cloudflare/circl v1.3.3 h1:fE/Qz0QdIGqeWfnwq0RE0R7MI51s0M2E4Ga9kq5AEMs=
github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA=
github.com/cyphar/filepath-securejoin v0.2.4 h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH53EtKeQYTC3kyg=
github.com/cyphar/filepath-securejoin v0.2.4/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
github.com/elazarl/goproxy v0.0.0-20230808193330-2592e75ae04a h1:mATvB/9r/3gvcejNsXKSkQ6lcIaNec2nyfOdlTBR2lU=
github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc=
github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ=
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/go-git/gcfg v1.5.0 h1:Q5ViNfGF8zFgyJWPqYwA7qGFoMTEiBmdlkcfRmpIMa4=
github.com/go-git/gcfg v1.5.0/go.mod h1:5m20vg6GwYabIxaOonVkTdrILxQMpEShl1xiMF4ua+E=
github.com/go-git/go-billy/v5 v5.3.1/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0=
github.com/go-git/go-billy/v5 v5.4.1 h1:Uwp5tDRkPr+l/TnbHOQzp+tmJfLceOlbVucgpTz8ix4=
github.com/go-git/go-billy/v5 v5.4.1/go.mod h1:vjbugF6Fz7JIflbVpl1hJsGjSHNltrSw45YK/ukIvQg=
github.com/go-git/go-git-fixtures/v4 v4.3.1 h1:y5z6dd3qi8Hl+stezc8p3JxDkoTRqMAlKnXHuzrfjTQ=
github.com/go-git/go-git-fixtures/v4 v4.3.1/go.mod h1:8LHG1a3SRW71ettAD/jW13h8c6AqjVSeL11RAdgaqpo=
github.com/go-git/go-git/v5 v5.6.1 h1:q4ZRqQl4pR/ZJHc1L5CFjGA1a10u76aV1iC+nh+bHsk=
github.com/go-git/go-git/v5 v5.6.1/go.mod h1:mvyoL6Unz0PiTQrGQfSfiLFhBH1c1e84ylC2MDs4ee8=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI=
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic=
github.com/go-git/go-billy/v5 v5.5.0 h1:yEY4yhzCDuMGSv83oGxiBotRzhwhNr8VZyphhiu+mTU=
github.com/go-git/go-billy/v5 v5.5.0/go.mod h1:hmexnoNsr2SJU1Ju67OaNz5ASJY3+sHgFRpCtpDCKow=
github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMje31YglSBqCdIqdhKBW8lokaMrL3uTkpGYlE2OOT4=
github.com/go-git/go-git/v5 v5.11.0 h1:XIZc1p+8YzypNr34itUfSvYJcv+eYdTnTvOZ2vD3cA4=
github.com/go-git/go-git/v5 v5.11.0/go.mod h1:6GFcX2P3NM7FPBfpePbpLd21XxsgdAt+lKqXmCUiUCY=
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE=
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/gorilla/css v1.0.0 h1:BQqNyPTi50JCFMTw/b67hByjMVXZRwGha6wxVGkeihY=
github.com/gorilla/css v1.0.0/go.mod h1:Dn721qIggHpt4+EFCcTLTU/vk5ySda2ReITrtgBl60c=
github.com/imdario/mergo v0.3.13/go.mod h1:4lJ1jqUDcsbIECGy0RUJAXNIhg+6ocWgb1ALK2O4oXg=
github.com/imdario/mergo v0.3.15 h1:M8XP7IuFNsqUx6VPK2P9OSmsYsI/YFaGil0uD21V3dM=
github.com/imdario/mergo v0.3.15/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY=
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A=
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=
github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4=
github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4=
github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/matryer/is v1.2.0 h1:92UTHpy8CDwaJ08GqLDzhhuixiBUUD1p3AU6PHddz4A=
github.com/matryer/is v1.2.0/go.mod h1:2fLPjFQM9rhQ15aVEtbuwhJinnOqrmgXPNdZsdwlWXA=
github.com/microcosm-cc/bluemonday v1.0.23 h1:SMZe2IGa0NuHvnVNAZ+6B38gsTbi5e4sViiWJyDDqFY=
github.com/microcosm-cc/bluemonday v1.0.23/go.mod h1:mN70sk7UkkF8TUr2IGBpNN0jAgStuPzlK76QuruE/z4=
github.com/mmcloughlin/avo v0.5.0/go.mod h1:ChHFdoV7ql95Wi7vuq2YT1bwCJqiWdZrQ1im3VujLYM=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI=
github.com/pjbgf/sha1cd v0.3.0 h1:4D5XXmUUBUl/xQ6IjCkEAbqXskkq/4O7LmGn0AqMDs4=
github.com/pjbgf/sha1cd v0.3.0/go.mod h1:nZ1rrWOcGJ5uZgEEVL1VUM9iRQiZvWdbZjkKyFzPPsI=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
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/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/skeema/knownhosts v1.1.0 h1:Wvr9V0MxhjRbl3f9nMnKnFfiWTJmtECJ9Njkea3ysW0=
github.com/skeema/knownhosts v1.1.0/go.mod h1:sKFq3RD6/TKZkSWn8boUbDC7Qkgcv+8XXijpFO6roag=
github.com/skeema/knownhosts v1.2.1 h1:SHWdIUa82uGZz+F+47k8SY4QhhI291cXCpopT1lK2AQ=
github.com/skeema/knownhosts v1.2.1/go.mod h1:xYbVRSPxqBZFrdmDyMmsOs+uX1UZC3nTN3ThzgDxUwo=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM=
github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
golang.org/x/arch v0.1.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.0.0-20220826181053-bd7e27e6170d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw=
golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58=
golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
golang.org/x/crypto v0.8.0 h1:pd9TJtTueMTVQXzk8E2XESSMQDj/U7OUu0PqJqPXQjQ=
golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE=
golang.org/x/crypto v0.16.0 h1:mMMrFzRSCF0GvB7Ne27XVtVAaXLrPmgPC7/v0tkwHaY=
golang.org/x/crypto v0.16.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.10.0 h1:lFO9qtOdlre5W1jxS3r/4szv2/6iXxScdzjoBMXNhYk=
golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc=
golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco=
golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
golang.org/x/net v0.9.0 h1:aWJ/m6xSmxWBx+V0XRHTlrYrPG56jKsLdTFmsSsCzOM=
golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=
golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c=
golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/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-20220825204002-c680a09ffe64/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU=
golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc=
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
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-20220722155259-a9ba230a4035/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=
golang.org/x/term v0.7.0 h1:BEvjmm5fURWqcfbSKTdpkDXYBrUS1c0m8agp14W48vQ=
golang.org/x/term v0.15.0 h1:y/Oo/a/q3IXu26lQgl04j/gjuBDOBlx7X6Om1j2CPW4=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
@ -150,26 +124,20 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE=
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/tools v0.8.0 h1:vSDcovVPld282ceKgDimkRSC8kpaH1dgyc9UMzlt84Y=
golang.org/x/tools v0.8.0/go.mod h1:JxBZ99ISMI5ViVkT1tr6tdNmXeTrcpVSD3vZ1RsRdN4=
golang.org/x/tools v0.13.0 h1:Iey4qkscZuv0VvIt8E0neZjtPVQFSc870HQ448QgEmQ=
golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME=
gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
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.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=

View File

@ -18,7 +18,12 @@ func (d *deps) InfoRefs(w http.ResponseWriter, r *http.Request) {
name := flow.Param(r.Context(), "name")
name = filepath.Clean(name)
repo := filepath.Join(d.c.Repo.ScanPath, name)
repo := d.c.Repo.ScanPath
category := flow.Param(r.Context(), "category")
if category != "" {
repo = filepath.Join(repo, category)
}
repo = filepath.Join(repo, name)
w.Header().Set("content-type", "application/x-git-upload-pack-advertisement")
@ -34,9 +39,15 @@ func (d *deps) InfoRefs(w http.ResponseWriter, r *http.Request) {
srv := server.NewServer(loader)
session, err := srv.NewUploadPackSession(ep, nil)
if err != nil {
http.Error(w, err.Error(), 500)
log.Printf("git: %s", err)
return
billyfs := osfs.New(repo + ".git")
loader := server.NewFilesystemLoader(billyfs)
srv := server.NewServer(loader)
session, err = srv.NewUploadPackSession(ep, nil)
if err != nil {
http.Error(w, err.Error(), 500)
log.Printf("git: %s", err)
return
}
}
ar, err := session.AdvertisedReferencesContext(r.Context())
@ -64,7 +75,12 @@ func (d *deps) UploadPack(w http.ResponseWriter, r *http.Request) {
name := flow.Param(r.Context(), "name")
name = filepath.Clean(name)
repo := filepath.Join(d.c.Repo.ScanPath, name)
repo := d.c.Repo.ScanPath
category := flow.Param(r.Context(), "category")
if category != "" {
repo = filepath.Join(repo, category)
}
repo = filepath.Join(repo, name)
w.Header().Set("content-type", "application/x-git-upload-pack-result")
@ -88,9 +104,15 @@ func (d *deps) UploadPack(w http.ResponseWriter, r *http.Request) {
svr := server.NewServer(loader)
session, err := svr.NewUploadPackSession(ep, nil)
if err != nil {
http.Error(w, err.Error(), 500)
log.Printf("git: %s", err)
return
billyfs := osfs.New(repo + ".git")
loader := server.NewFilesystemLoader(billyfs)
svr := server.NewServer(loader)
session, err = svr.NewUploadPackSession(ep, nil)
if err != nil {
http.Error(w, err.Error(), 500)
log.Printf("git: %s", err)
return
}
}
res, err := session.UploadPack(r.Context(), upr)

View File

@ -39,12 +39,19 @@ func Handlers(c *config.Config) *flow.Mux {
mux.HandleFunc("/", d.Index, "GET")
mux.HandleFunc("/static/:file", d.ServeStatic, "GET")
mux.HandleFunc("/:category/:name", d.Multiplex, "GET", "POST")
mux.HandleFunc("/:name", d.Multiplex, "GET", "POST")
mux.HandleFunc("/:category/:name/tree/:ref/...", d.RepoTree, "GET")
mux.HandleFunc("/:name/tree/:ref/...", d.RepoTree, "GET")
mux.HandleFunc("/:category/:name/blob/:ref/...", d.FileContent, "GET")
mux.HandleFunc("/:name/blob/:ref/...", d.FileContent, "GET")
mux.HandleFunc("/:category/:name/log/:ref", d.Log, "GET")
mux.HandleFunc("/:name/log/:ref", d.Log, "GET")
mux.HandleFunc("/:category/:name/commit/:ref", d.Diff, "GET")
mux.HandleFunc("/:name/commit/:ref", d.Diff, "GET")
mux.HandleFunc("/:category/:name/refs", d.Refs, "GET")
mux.HandleFunc("/:name/refs", d.Refs, "GET")
mux.HandleFunc("/:category/:name/...", d.Multiplex, "GET", "POST")
mux.HandleFunc("/:name/...", d.Multiplex, "GET", "POST")
return mux

View File

@ -1,6 +1,7 @@
package routes
import (
"errors"
"fmt"
"html/template"
"log"
@ -8,12 +9,14 @@ import (
"os"
"path/filepath"
"sort"
"strings"
"time"
"git.icyphox.sh/legit/config"
"git.icyphox.sh/legit/git"
"github.com/alexedwards/flow"
"github.com/dustin/go-humanize"
gogit "github.com/go-git/go-git/v5"
"github.com/microcosm-cc/bluemonday"
"github.com/russross/blackfriday/v2"
)
@ -22,6 +25,11 @@ type deps struct {
c *config.Config
}
type info struct {
Name, Path, Desc, Idle string
d time.Time
}
func (d *deps) Index(w http.ResponseWriter, r *http.Request) {
dirs, err := os.ReadDir(d.c.Repo.ScanPath)
if err != nil {
@ -30,12 +38,7 @@ func (d *deps) Index(w http.ResponseWriter, r *http.Request) {
return
}
type info struct {
Name, Desc, Idle string
d time.Time
}
infos := []info{}
categories := make(map[string][]info)
for _, dir := range dirs {
if d.isIgnored(dir.Name()) {
@ -44,7 +47,17 @@ func (d *deps) Index(w http.ResponseWriter, r *http.Request) {
path := filepath.Join(d.c.Repo.ScanPath, dir.Name())
gr, err := git.Open(path, "")
if err != nil {
if errors.Is(err, gogit.ErrRepositoryNotExists) {
log.Printf("reading category: %s", dir.Name())
infos, err := d.IndexCategory(path, dir.Name())
if err != nil {
log.Printf("reading category: %s", err)
}
if len(infos) > 0 {
categories[dir.Name()] = infos
}
continue
} else if err != nil {
log.Println(err)
continue
}
@ -57,25 +70,29 @@ func (d *deps) Index(w http.ResponseWriter, r *http.Request) {
}
desc := getDescription(path)
name := strings.TrimSuffix(dir.Name(), ".git")
infos = append(infos, info{
Name: dir.Name(),
categories[""] = append(categories[""], info{
Name: name,
Path: name,
Desc: desc,
Idle: humanize.Time(c.Author.When),
d: c.Author.When,
})
}
sort.Slice(infos, func(i, j int) bool {
return infos[j].d.Before(infos[i].d)
})
for _, infos := range categories {
sort.Slice(infos, func(i, j int) bool {
return infos[j].d.Before(infos[i].d)
})
}
tpath := filepath.Join(d.c.Dirs.Templates, "*")
t := template.Must(template.ParseGlob(tpath))
data := make(map[string]interface{})
data["meta"] = d.c.Meta
data["info"] = infos
data["categories"] = categories
if err := t.ExecuteTemplate(w, "index", data); err != nil {
log.Println(err)
@ -83,6 +100,58 @@ func (d *deps) Index(w http.ResponseWriter, r *http.Request) {
}
}
func (d *deps) IndexCategory(scanpath string, category string) ([]info, error) {
dirs, err := os.ReadDir(scanpath)
if err != nil {
return nil, fmt.Errorf("reading scan path: %s", err)
}
infos := []info{}
for _, dir := range dirs {
if d.isIgnored(dir.Name()) {
continue
}
path := filepath.Join(scanpath, dir.Name())
gr, err := git.Open(path, "")
if errors.Is(err, gogit.ErrRepositoryNotExists) {
log.Println(path)
folder_infos, err := d.IndexCategory(path, category)
if err != nil {
log.Println(err)
continue
}
infos = append(infos, folder_infos...)
continue
} else if err != nil {
log.Println(err)
continue
}
c, err := gr.LastCommit()
if err != nil {
return nil, err
}
desc := getDescription(path)
repodir := filepath.Join(scanpath, dir.Name())
repopath := strings.Split(repodir, category)
name := strings.TrimSuffix(repopath[len(repopath)-1], ".git")
name = strings.TrimPrefix(name, "/")
infos = append(infos, info{
Name: name,
Path: category + "/" + name,
Desc: desc,
Idle: humanize.Time(c.Author.When),
d: c.Author.When,
})
}
return infos, nil
}
func (d *deps) RepoIndex(w http.ResponseWriter, r *http.Request) {
name := flow.Param(r.Context(), "name")
if d.isIgnored(name) {
@ -90,12 +159,22 @@ func (d *deps) RepoIndex(w http.ResponseWriter, r *http.Request) {
return
}
name = filepath.Clean(name)
path := filepath.Join(d.c.Repo.ScanPath, name)
path := d.c.Repo.ScanPath
category := flow.Param(r.Context(), "category")
if category != "" {
path = filepath.Join(path, category)
log.Println(category)
}
path = filepath.Join(path, name)
log.Println(path)
gr, err := git.Open(path, "")
if err != nil {
d.Write404(w)
return
gr, err = git.Open(path+".git", "")
if err != nil {
d.Write404(w)
return
}
}
commits, err := gr.Commits()
@ -147,6 +226,11 @@ func (d *deps) RepoIndex(w http.ResponseWriter, r *http.Request) {
data := make(map[string]any)
data["name"] = name
if category != "" {
data["repo"] = filepath.Join(category, name)
} else {
data["repo"] = name
}
data["ref"] = mainBranch
data["readme"] = readmeContent
data["commits"] = commits
@ -173,11 +257,19 @@ func (d *deps) RepoTree(w http.ResponseWriter, r *http.Request) {
ref := flow.Param(r.Context(), "ref")
name = filepath.Clean(name)
path := filepath.Join(d.c.Repo.ScanPath, name)
path := d.c.Repo.ScanPath
category := flow.Param(r.Context(), "category")
if category != "" {
path = filepath.Join(path, category)
}
path = filepath.Join(path, name)
gr, err := git.Open(path, ref)
if err != nil {
d.Write404(w)
return
gr, err = git.Open(path+".git", ref)
if err != nil {
d.Write404(w)
return
}
}
files, err := gr.FileTree(treePath)
@ -189,6 +281,11 @@ func (d *deps) RepoTree(w http.ResponseWriter, r *http.Request) {
data := make(map[string]any)
data["name"] = name
if category != "" {
data["repo"] = filepath.Join(category, name)
} else {
data["repo"] = name
}
data["ref"] = ref
data["parent"] = treePath
data["desc"] = getDescription(path)
@ -208,16 +305,29 @@ func (d *deps) FileContent(w http.ResponseWriter, r *http.Request) {
ref := flow.Param(r.Context(), "ref")
name = filepath.Clean(name)
path := filepath.Join(d.c.Repo.ScanPath, name)
path := d.c.Repo.ScanPath
category := flow.Param(r.Context(), "category")
if category != "" {
path = filepath.Join(path, category)
}
path = filepath.Join(path, name)
gr, err := git.Open(path, ref)
if err != nil {
d.Write404(w)
return
gr, err = git.Open(path+".git", ref)
if err != nil {
d.Write404(w)
return
}
}
contents, err := gr.FileContent(treePath)
data := make(map[string]any)
data["name"] = name
if category != "" {
data["repo"] = filepath.Join(category, name)
} else {
data["repo"] = name
}
data["ref"] = ref
data["desc"] = getDescription(path)
data["path"] = treePath
@ -234,11 +344,19 @@ func (d *deps) Log(w http.ResponseWriter, r *http.Request) {
}
ref := flow.Param(r.Context(), "ref")
path := filepath.Join(d.c.Repo.ScanPath, name)
path := d.c.Repo.ScanPath
category := flow.Param(r.Context(), "category")
if category != "" {
path = filepath.Join(path, category)
}
path = filepath.Join(path, name)
gr, err := git.Open(path, ref)
if err != nil {
d.Write404(w)
return
gr, err = git.Open(path+".git", ref)
if err != nil {
d.Write404(w)
return
}
}
commits, err := gr.Commits()
@ -255,6 +373,11 @@ func (d *deps) Log(w http.ResponseWriter, r *http.Request) {
data["commits"] = commits
data["meta"] = d.c.Meta
data["name"] = name
if category != "" {
data["repo"] = filepath.Join(category, name)
} else {
data["repo"] = name
}
data["ref"] = ref
data["desc"] = getDescription(path)
data["log"] = true
@ -273,11 +396,19 @@ func (d *deps) Diff(w http.ResponseWriter, r *http.Request) {
}
ref := flow.Param(r.Context(), "ref")
path := filepath.Join(d.c.Repo.ScanPath, name)
path := d.c.Repo.ScanPath
category := flow.Param(r.Context(), "category")
if category != "" {
path = filepath.Join(path, category)
}
path = filepath.Join(path, name)
gr, err := git.Open(path, ref)
if err != nil {
d.Write404(w)
return
gr, err = git.Open(path+".git", ref)
if err != nil {
d.Write404(w)
return
}
}
diff, err := gr.Diff()
@ -297,6 +428,11 @@ func (d *deps) Diff(w http.ResponseWriter, r *http.Request) {
data["diff"] = diff.Diff
data["meta"] = d.c.Meta
data["name"] = name
if category != "" {
data["repo"] = filepath.Join(category, name)
} else {
data["repo"] = name
}
data["ref"] = ref
data["desc"] = getDescription(path)
@ -313,11 +449,19 @@ func (d *deps) Refs(w http.ResponseWriter, r *http.Request) {
return
}
path := filepath.Join(d.c.Repo.ScanPath, name)
path := d.c.Repo.ScanPath
category := flow.Param(r.Context(), "category")
if category != "" {
path = filepath.Join(path, category)
}
path = filepath.Join(path, name)
gr, err := git.Open(path, "")
if err != nil {
d.Write404(w)
return
gr, err = git.Open(path+".git", "")
if err != nil {
d.Write404(w)
return
}
}
tags, err := gr.Tags()
@ -340,6 +484,11 @@ func (d *deps) Refs(w http.ResponseWriter, r *http.Request) {
data["meta"] = d.c.Meta
data["name"] = name
if category != "" {
data["repo"] = filepath.Join(category, name)
} else {
data["repo"] = name
}
data["branches"] = branches
data["tags"] = tags
data["desc"] = getDescription(path)

BIN
static/bunny.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 507 KiB

View File

@ -1,18 +1,30 @@
:root {
--light: #f4f4f4;
--cyan: #509c93;
--light-gray: #eee;
--medium-gray: #ddd;
--gray: #6a6a6a;
--dark: #444;
--darker: #222;
--light: #224520;
--cyan: #285125;
--light-gray: #336830;
--medium-gray: #dbd7d4;
--gray: #dbd7d4;
--dark: #f3d0aa;
--darker: #f3d0aa;
--sans-font: "InterVar", -apple-system, BlinkMacSystemFont, "Roboto", "Segoe UI", sans-serif;
--display-font: "InterDisplay", -apple-system, BlinkMacSystemFont, "Roboto", "Segoe UI", sans-serif;
--mono-font: 'SF Mono', SFMono-Regular, ui-monospace, 'DejaVu Sans Mono', 'Roboto Mono', Menlo, Consolas, monospace;
--sans-font: "Darumadrop One", -apple-system, BlinkMacSystemFont, "Roboto", "Segoe UI", sans-serif;
--display-font: "Darumadrop One", -apple-system, BlinkMacSystemFont, "Roboto", "Segoe UI", sans-serif;
--mono-font: 'Victor Mono', 'VictorMono Nerd Font', SFMono-Regular, ui-monospace, 'DejaVu Sans Mono', 'Roboto Mono', Menlo, Consolas, monospace;
}
header {
display: flex;
gap: 2em;
flex-wrap: wrap;
}
header img {
max-width: 128px;
max-height: 128px;
}
html {
color: var(--dark);
background: var(--light);
-webkit-text-size-adjust: none;
font-family: var(--sans-font);
@ -39,13 +51,17 @@ body {
margin: 40px auto;
}
main, footer {
main,
footer {
font-size: 1rem;
padding: 0;
line-height: 160%;
}
main h1, h2, h3, strong {
main h1,
h2,
h3,
strong {
font-family: var(--display-font);
font-weight: 500;
}
@ -63,7 +79,8 @@ main h2 {
font-size: 18px;
}
main h2, h3 {
main h2,
h3 {
padding: 20px 0 15px 0;
}
@ -101,13 +118,17 @@ a:hover {
}
.index {
padding-top: 2em;
display: grid;
grid-template-columns: 6em 1fr minmax(0, 7em);
grid-row-gap: 0.5em;
min-width: 0;
}
.index-category {
margin-top: 2em;
color: var(--gray);
}
.clone-url {
padding-top: 2rem;
}
@ -145,9 +166,11 @@ a:hover {
white-space: pre-wrap;
}
.mode, .size {
.mode,
.size {
font-family: var(--mono-font);
}
.size {
text-align: right;
}
@ -183,7 +206,8 @@ a:hover {
padding: 1rem 0 1rem 0;
}
.commit-hash, .commit-email {
.commit-hash,
.commit-email {
font-family: var(--mono-font);
}
@ -303,4 +327,4 @@ a:hover {
pre {
font-size: 0.8rem;
}
}
}

View File

@ -2,74 +2,76 @@
<html>
{{ template "head" . }}
{{ template "repoheader" . }}
<body>
{{ template "nav" . }}
<main>
<section class="commit">
<pre>
{{- .commit.Message -}}
</pre>
<div class="commit-info">
{{ .commit.Author.Name }} <a href="mailto:{{ .commit.Author.Email }}" class="commit-email">{{ .commit.Author.Email}}</a>
{{ template "repoheader" . }}
<body>
{{ template "nav" . }}
<main>
<section class="commit">
<pre>
{{- .commit.Message -}}
</pre>
<div class="commit-info">
{{ .commit.Author.Name }} <a href="mailto:{{ .commit.Author.Email }}" class="commit-email">{{
.commit.Author.Email}}</a>
<div>{{ .commit.Author.When.Format "Mon, 02 Jan 2006 15:04:05 -0700" }}</div>
</div>
</div>
<div>
<div>
<strong>commit</strong>
<p><a href="/{{ .name }}/commit/{{ .commit.This }}" class="commit-hash">
{{ .commit.This }}
</a>
<p><a href="/{{ .repo }}/commit/{{ .commit.This }}" class="commit-hash">
{{ .commit.This }}
</a>
</p>
</div>
</div>
{{ if .commit.Parent }}
<div>
{{ if .commit.Parent }}
<div>
<strong>parent</strong>
<p><a href="/{{ .name }}/commit/{{ .commit.Parent }}" class="commit-hash">
{{ .commit.Parent }}
</a></p>
</div>
<p><a href="/{{ .repo }}/commit/{{ .commit.Parent }}" class="commit-hash">
{{ .commit.Parent }}
</a></p>
</div>
{{ end }}
<div class="diff-stat">
<div>
{{ end }}
<div class="diff-stat">
<div>
{{ .stat.FilesChanged }} files changed,
{{ .stat.Insertions }} insertions(+),
{{ .stat.Deletions }} deletions(-)
</div>
<div>
<br>
<strong>jump to</strong>
{{ range .diff }}
<ul>
<li><a href="#{{ .Name.New }}">{{ .Name.New }}</a></li>
</ul>
{{ end }}
</div>
</div>
</section>
<section>
{{ $repo := .name }}
{{ $this := .commit.This }}
{{ $parent := .commit.Parent }}
{{ range .diff }}
<div id="{{ .Name.New }}">
<div class="diff">
{{ if .IsNew }}
<span class="diff-type">A</span>
{{ end }}
{{ if .IsDelete }}
<span class="diff-type">D</span>
{{ end }}
{{ if not (or .IsNew .IsDelete) }}
<span class="diff-type">M</span>
{{ end }}
<div>
<br>
<strong>jump to</strong>
{{ range .diff }}
<ul>
<li><a href="#{{ .Name.New }}">{{ .Name.New }}</a></li>
</ul>
{{ end }}
</div>
</div>
</section>
<section>
{{ $repo := .repo }}
{{ $this := .commit.This }}
{{ $parent := .commit.Parent }}
{{ range .diff }}
<div id="{{ .Name.New }}">
<div class="diff">
{{ if .IsNew }}
<span class="diff-type">A</span>
{{ end }}
{{ if .IsDelete }}
<span class="diff-type">D</span>
{{ end }}
{{ if not (or .IsNew .IsDelete) }}
<span class="diff-type">M</span>
{{ end }}
{{ if .Name.Old }}
<a href="/{{ $repo }}/blob/{{ $parent }}/{{ .Name.Old }}">{{ .Name.Old }}</a>
{{ if .Name.New }}
&#8594;
<a href="/{{ $repo }}/blob/{{ $this }}/{{ .Name.New }}">{{ .Name.New }}</a>
&#8594;
<a href="/{{ $repo }}/blob/{{ $this }}/{{ .Name.New }}">{{ .Name.New }}</a>
{{ end }}
{{ else }}
<a href="/{{ $repo }}/blob/{{ $this }}/{{ .Name.New }}">{{ .Name.New }}</a>
@ -77,28 +79,29 @@
{{ if .IsBinary }}
<p>Not showing binary file.</p>
{{ else }}
<pre>
<pre>
{{- range .TextFragments -}}
<p>{{- .Header -}}</p>
{{- range .Lines -}}
{{- if eq .Op.String "+" -}}
<span class="diff-add">{{ .String }}</span>
{{- end -}}
{{- if eq .Op.String "-" -}}
<span class="diff-del">{{ .String }}</span>
{{- end -}}
{{- if eq .Op.String " " -}}
<span class="diff-noop">{{ .String }}</span>
{{- end -}}
{{- if eq .Op.String "+" -}}
<span class="diff-add">{{ .String }}</span>
{{- end -}}
{{- if eq .Op.String "-" -}}
<span class="diff-del">{{ .String }}</span>
{{- end -}}
{{- if eq .Op.String " " -}}
<span class="diff-noop">{{ .String }}</span>
{{- end -}}
{{- end -}}
{{- end -}}
</pre>
</div>
</div>
{{ end }}
</section>
</main>
</body>
{{- end -}}
{{- end -}}
</pre>
</div>
</div>
{{ end }}
</section>
</main>
</body>
</html>
{{ end }}
{{ end }}

View File

@ -1,33 +1,34 @@
{{ define "head" }}
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="/static/style.css" type="text/css">
<link rel="stylesheet" href="https://cdn.icyphox.sh/fonts/inter.css" type="text/css">
<link rel="icon" type="image/png" size="32x32" href="/static/legit.png">
{{ if .parent }}
<title>{{ .meta.Title }} &mdash; {{ .name }} ({{ .ref }}): {{ .parent }}/</title>
{{ else if .path }}
<title>{{ .meta.Title }} &mdash; {{ .name }} ({{ .ref }}): {{ .path }}</title>
{{ else if .files }}
<title>{{ .meta.Title }} &mdash; {{ .name }} ({{ .ref }})</title>
{{ else if .commit }}
<title>{{ .meta.Title }} &mdash; {{ .name }}: {{ .commit.This }}</title>
{{ else if .branches }}
<title>{{ .meta.Title }} &mdash; {{ .name }}: refs</title>
{{ else if .commits }}
{{ if .log }}
<title>{{ .meta.Title }} &mdash; {{ .name }}: log</title>
{{ else }}
<title>{{ .meta.Title }} &mdash; {{ .name }}</title>
{{ end }}
{{ else }}
<title>{{ .meta.Title }}</title>
{{ end }}
{{ if and .servername .gomod }}
<meta name="go-import" content="{{ .servername}}/{{ .name }} git https://{{ .servername }}/{{ .name }}">
{{ end }}
<!-- other meta tags here -->
</head>
{{ end }}
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="/static/style.css" type="text/css">
<link rel="stylesheet" href="https://cdn.icyphox.sh/fonts/inter.css" type="text/css">
<link rel="icon" type="image/png" size="32x32" href="/static/bunny.png">
{{ if .parent }}
<title>{{ .meta.Title }} &mdash; {{ .name }} ({{ .ref }}): {{ .parent }}/</title>
{{ else if .path }}
<title>{{ .meta.Title }} &mdash; {{ .name }} ({{ .ref }}): {{ .path }}</title>
{{ else if .files }}
<title>{{ .meta.Title }} &mdash; {{ .name }} ({{ .ref }})</title>
{{ else if .commit }}
<title>{{ .meta.Title }} &mdash; {{ .name }}: {{ .commit.This }}</title>
{{ else if .branches }}
<title>{{ .meta.Title }} &mdash; {{ .name }}: refs</title>
{{ else if .commits }}
{{ if .log }}
<title>{{ .meta.Title }} &mdash; {{ .name }}: log</title>
{{ else }}
<title>{{ .meta.Title }} &mdash; {{ .name }}</title>
{{ end }}
{{ else }}
<title>{{ .meta.Title }}</title>
{{ end }}
{{ if and .servername .gomod }}
<meta name="go-import" content="{{ .servername}}/{{ .name }} git https://{{ .servername }}/{{ .name }}">
{{ end }}
<!-- other meta tags here -->
</head>
{{ end }}

View File

@ -2,20 +2,30 @@
<html>
{{ template "head" . }}
<header>
<header>
<div>
<img src="/static/bunny.png">
</div>
<div>
<h1>{{ .meta.Title }}</h1>
<h2>{{ .meta.Description }}</h2>
</header>
<body>
<main>
<div class="index">
{{ range .info }}
<div class="index-name"><a href="/{{ .Name }}">{{ .Name }}</a></div>
<div class="desc">{{ .Desc }}</div>
<div>{{ .Idle }}</div>
</div>
</header>
<body>
<main>
{{ range $key, $value := .categories }}
<div class="index-category">{{ $key }}</div>
<div class="index">
{{ range $value }}
<div class="index-name"><a href="/{{ .Path }}">{{ .Name }}</a></div>
<div class="desc">{{ .Desc }}</div>
<div>{{ .Idle }}</div>
{{ end }}
</div>
</main>
</body>
</div>
{{ end }}
</main>
</body>
</html>
{{ end }}

View File

@ -2,24 +2,26 @@
<html>
{{ template "head" . }}
{{ template "repoheader" . }}
<body>
{{ template "nav" . }}
<main>
{{ $repo := .name }}
<div class="log">
{{ range .commits }}
<div>
<div><a href="/{{ $repo }}/commit/{{ .Hash.String }}" class="commit-hash">{{ slice .Hash.String 0 8 }}</a></div>
<pre>{{ .Message }}</pre>
</div>
<div class="commit-info">
{{ .Author.Name }} <a href="mailto:{{ .Author.Email }}" class="commit-email">{{ .Author.Email }}</a>
<div>{{ .Author.When.Format "Mon, 02 Jan 2006 15:04:05 -0700" }}</div>
</div>
{{ end }}
{{ template "repoheader" . }}
<body>
{{ template "nav" . }}
<main>
{{ $repo := .repo }}
<div class="log">
{{ range .commits }}
<div>
<div><a href="/{{ $repo }}/commit/{{ .Hash.String }}" class="commit-hash">{{ slice .Hash.String 0 8 }}</a></div>
<pre>{{ .Message }}</pre>
</div>
</main>
</body>
<div class="commit-info">
{{ .Author.Name }} <a href="mailto:{{ .Author.Email }}" class="commit-email">{{ .Author.Email }}</a>
<div>{{ .Author.When.Format "Mon, 02 Jan 2006 15:04:05 -0700" }}</div>
</div>
{{ end }}
</div>
</main>
</body>
</html>
{{ end }}
{{ end }}

View File

@ -1,14 +1,14 @@
{{ define "nav" }}
<nav>
<ul>
{{ if .name }}
<li><a href="/{{ .name }}">summary</a>
<li><a href="/{{ .name }}/refs">refs</a>
<nav>
<ul>
{{ if .repo }}
<li><a href="/{{ .repo }}">summary</a>
<li><a href="/{{ .repo }}/refs">refs</a>
{{ if .ref }}
<li><a href="/{{ .name }}/tree/{{ .ref }}/">tree</a>
<li><a href="/{{ .name }}/log/{{ .ref }}">log</a>
<li><a href="/{{ .repo }}/tree/{{ .ref }}/">tree</a>
<li><a href="/{{ .repo }}/log/{{ .ref }}">log</a>
{{ end }}
{{ end }}
</ul>
</nav>
{{ end }}
{{ end }}
</ul>
</nav>
{{ end }}

View File

@ -2,37 +2,39 @@
<html>
{{ template "head" . }}
{{ template "repoheader" . }}
<body>
{{ template "nav" . }}
<main>
{{ $name := .name }}
<h3>branches</h3>
<div class="refs">
{{ template "repoheader" . }}
<body>
{{ template "nav" . }}
<main>
{{ $name := .repo }}
<h3>branches</h3>
<div class="refs">
{{ range .branches }}
<div>
<div>
<strong>{{ .Name.Short }}</strong>
<a href="/{{ $name }}/tree/{{ .Name.Short }}/">browse</a>
<a href="/{{ $name }}/log/{{ .Name.Short }}">log</a>
</div>
{{ end }}
</div>
{{ if .tags }}
<h3>tags</h3>
<div class="refs">
{{ end }}
</div>
{{ if .tags }}
<h3>tags</h3>
<div class="refs">
{{ range .tags }}
<div>
<strong>{{ .Name }}</strong>
<a href="/{{ $name }}/tree/{{ .Name }}/">browse</a>
<a href="/{{ $name }}/log/{{ .Name }}">log</a>
{{ if .Message }}
<pre>{{ .Message }}</pre>
<strong>{{ .Name }}</strong>
<a href="/{{ $name }}/tree/{{ .Name }}/">browse</a>
<a href="/{{ $name }}/log/{{ .Name }}">log</a>
{{ if .Message }}
<pre>{{ .Message }}</pre>
</div>
{{ end }}
{{ end }}
</div>
{{ end }}
</main>
</body>
</div>
{{ end }}
</main>
</body>
</html>
{{ end }}
{{ end }}

View File

@ -1,12 +1,12 @@
{{ define "repoheader" }}
<header>
<h2>
<a href="/">all repos</a>
&mdash; {{ .name }}
<a href="/">all repos</a>
&mdash; {{ .repo }}
{{ if .ref }}
<span class="ref">@ {{ .ref }}</span>
{{ end }}
</h2>
<h3 class="desc">{{ .desc }}</h3>
</header>
{{ end }}
{{ end }}

View File

@ -4,35 +4,36 @@
{{ template "repoheader" . }}
<body>
{{ template "nav" . }}
<main>
{{ $repo := .name }}
<div class="log">
{{ range .commits }}
<div>
<div><a href="/{{ $repo }}/commit/{{ .Hash.String }}" class="commit-hash">{{ slice .Hash.String 0 8 }}</a></div>
<pre>{{ .Message }}</pre>
</div>
<div class="commit-info">
{{ .Author.Name }} <a href="mailto:{{ .Author.Email }}" class="commit-email">{{ .Author.Email }}</a>
<div>{{ .Author.When.Format "Mon, 02 Jan 2006 15:04:05 -0700" }}</div>
</div>
{{ end }}
<body>
{{ template "nav" . }}
<main>
{{ $repo := .repo }}
<div class="log">
{{ range .commits }}
<div>
<div><a href="/{{ $repo }}/commit/{{ .Hash.String }}" class="commit-hash">{{ slice .Hash.String 0 8 }}</a></div>
<pre>{{ .Message }}</pre>
</div>
{{- if .readme }}
<article class="readme">
{{- .readme -}}
</article>
{{- end -}}
<div class="commit-info">
{{ .Author.Name }} <a href="mailto:{{ .Author.Email }}" class="commit-email">{{ .Author.Email }}</a>
<div>{{ .Author.When.Format "Mon, 02 Jan 2006 15:04:05 -0700" }}</div>
</div>
{{ end }}
</div>
{{- if .readme }}
<article class="readme">
{{- .readme -}}
</article>
{{- end -}}
<div class="clone-url">
<div class="clone-url">
<strong>clone</strong>
<pre>
git clone https://{{ .servername }}/{{ .name }}
</pre>
</div>
</main>
</body>
<pre>
git clone https://{{ .servername }}/{{ .repo }}
</pre>
</div>
</main>
</body>
</html>
{{ end }}
{{ end }}

View File

@ -3,53 +3,55 @@
{{ template "head" . }}
{{ template "repoheader" . }}
<body>
{{ template "nav" . }}
<main>
{{ $repo := .name }}
{{ $ref := .ref }}
{{ $parent := .parent }}
{{ template "repoheader" . }}
<div class="tree">
<body>
{{ template "nav" . }}
<main>
{{ $repo := .repo }}
{{ $ref := .ref }}
{{ $parent := .parent }}
<div class="tree">
{{ if $parent }}
<div></div>
<div></div>
<div><a href="/{{ $repo }}/tree/{{ $ref }}/{{ .dotdot }}">..</a></div>
{{ end }}
{{ range .files }}
{{ if not .IsFile }}
<div class="mode">{{ .Mode }}</div>
<div class="size">{{ .Size }}</div>
<div>
{{ if $parent }}
<div></div>
<div></div>
<div><a href="/{{ $repo }}/tree/{{ $ref }}/{{ .dotdot }}">..</a></div>
{{ end }}
{{ range .files }}
{{ if not .IsFile }}
<div class="mode">{{ .Mode }}</div>
<div class="size">{{ .Size }}</div>
<div>
{{ if $parent }}
<a href="/{{ $repo }}/tree/{{ $ref }}/{{ $parent }}/{{ .Name }}">{{ .Name }}/</a>
{{ else }}
<a href="/{{ $repo }}/tree/{{ $ref }}/{{ .Name }}">{{ .Name }}/</a>
{{ end }}
</div>
{{ end }}
{{ end }}
{{ range .files }}
{{ if .IsFile }}
<div class="mode">{{ .Mode }}</div>
<div class="size">{{ .Size }}</div>
<div>
{{ if $parent }}
<a href="/{{ $repo }}/blob/{{ $ref }}/{{ $parent }}/{{ .Name }}">{{ .Name }}</a>
{{ else }}
<a href="/{{ $repo }}/blob/{{ $ref }}/{{ .Name }}">{{ .Name }}</a>
{{ end }}
</div>
{{ end }}
<a href="/{{ $repo }}/tree/{{ $ref }}/{{ $parent }}/{{ .Name }}">{{ .Name }}/</a>
{{ else }}
<a href="/{{ $repo }}/tree/{{ $ref }}/{{ .Name }}">{{ .Name }}/</a>
{{ end }}
</div>
<article>
<pre>
{{- if .readme }}{{ .readme }}{{- end -}}
</pre>
</article>
</main>
</body>
{{ end }}
{{ end }}
{{ range .files }}
{{ if .IsFile }}
<div class="mode">{{ .Mode }}</div>
<div class="size">{{ .Size }}</div>
<div>
{{ if $parent }}
<a href="/{{ $repo }}/blob/{{ $ref }}/{{ $parent }}/{{ .Name }}">{{ .Name }}</a>
{{ else }}
<a href="/{{ $repo }}/blob/{{ $ref }}/{{ .Name }}">{{ .Name }}</a>
{{ end }}
</div>
{{ end }}
{{ end }}
</div>
<article>
<pre>
{{- if .readme }}{{ .readme }}{{- end -}}
</pre>
</article>
</main>
</body>
</html>
{{ end }}
{{ end }}