From 4534dffb865eb1a50bfbc291a5c3798183081caf Mon Sep 17 00:00:00 2001 From: "Gabriel A. Giovanini" Date: Sun, 26 May 2024 20:33:37 +0200 Subject: feat: Add actual git listing implementation --- go.mod | 22 ++++++++ go.sum | 103 ++++++++++++++++++++++++++++++++++++ main.go | 17 +++++- pkg/git/git.go | 82 +++++++++++++++++++++++++++++ pkg/handler/git.go | 9 +++- pkg/handler/status.go | 2 +- pkg/service/git.go | 51 +++++++++++++----- pkg/u/file.go | 21 ++++++++ pkg/u/list.go | 17 ++++++ pkg/u/list_test.go | 96 ++++++++++++++++++++++++++++++++++ pkg/u/util.go | 17 ------ pkg/u/util_test.go | 96 ---------------------------------- scss/main.scss | 7 ++- templates/base.qtpl | 1 + templates/base.qtpl.go | 129 +++++++++++++++++++++++----------------------- templates/gitlist.qtpl | 11 ++-- templates/gitlist.qtpl.go | 89 +++++++++++++++++--------------- 17 files changed, 530 insertions(+), 240 deletions(-) create mode 100644 pkg/git/git.go create mode 100644 pkg/u/file.go create mode 100644 pkg/u/list.go create mode 100644 pkg/u/list_test.go delete mode 100644 pkg/u/util.go delete mode 100644 pkg/u/util_test.go diff --git a/go.mod b/go.mod index ff4f2dd..2122f6b 100644 --- a/go.mod +++ b/go.mod @@ -11,6 +11,28 @@ require ( ) require ( + dario.cat/mergo v1.0.0 // indirect + github.com/Microsoft/go-winio v0.6.1 // indirect + github.com/ProtonMail/go-crypto v1.0.0 // indirect + github.com/cloudflare/circl v1.3.7 // indirect + github.com/cyphar/filepath-securejoin v0.2.4 // indirect github.com/dlclark/regexp2 v1.11.0 // indirect + github.com/emirpasic/gods v1.18.1 // indirect + github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect + github.com/go-git/go-billy/v5 v5.5.0 // indirect + github.com/go-git/go-git/v5 v5.12.0 // indirect + github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // 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.2-0.20230802210424-5b0b94c5c0d3 // indirect + github.com/skeema/knownhosts v1.2.2 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect + github.com/xanzy/ssh-agent v0.3.3 // indirect + golang.org/x/crypto v0.21.0 // indirect + golang.org/x/mod v0.12.0 // indirect + golang.org/x/net v0.22.0 // indirect + golang.org/x/sys v0.18.0 // indirect + golang.org/x/tools v0.13.0 // indirect + gopkg.in/warnings.v0 v0.1.2 // indirect ) diff --git a/go.sum b/go.sum index 15e574a..ba2d937 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,12 @@ +dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= +dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= git.sr.ht/~emersion/go-scfg v0.0.0-20240128091534-2ae16e782082 h1:9Udx5fm4vRtmgDIBjy2ef5QioHbzpw5oHabbhpAUyEw= git.sr.ht/~emersion/go-scfg v0.0.0-20240128091534-2ae16e782082/go.mod h1:ybgvEJTIx5XbaspSviB3KNa6OdPmAZqDoSud7z8fFlw= +github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY= +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 v1.0.0 h1:LRuvITjQWX+WIfr930YHG2HNfjR1uOfyf5vE0kC2U78= +github.com/ProtonMail/go-crypto v1.0.0/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0= github.com/alecthomas/assert/v2 v2.6.0 h1:o3WJwILtexrEUk3cUVal3oiQY2tfgr/FHWiz/v2n4FU= github.com/alecthomas/assert/v2 v2.6.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k= github.com/alecthomas/chroma/v2 v2.13.0 h1:VP72+99Fb2zEcYM0MeaWJmV+xQvz5v5cxRHd+ooU1lI= @@ -8,32 +15,128 @@ github.com/alecthomas/repr v0.4.0 h1:GhI2A8MACjfegCPVq9f1FLvIBS+DrQ2KQBFZP1iFzXc github.com/alecthomas/repr v0.4.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4= github.com/andybalholm/brotli v1.0.2/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y= github.com/andybalholm/brotli v1.0.3/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= +github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= +github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA= +github.com/cloudflare/circl v1.3.7 h1:qlCDlTPz2n9fu58M0Nh1J/JzcFpfgkFHHX3O35r5vcU= +github.com/cloudflare/circl v1.3.7/go.mod h1:sRTcRWXGLrKw6yIGJ+l7amYJFfAXbZG0kBSc8r4zxgA= +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/dlclark/regexp2 v1.11.0 h1:G/nrcoOa7ZXlpoa/91N3X7mM3r8eIlMBBJZvsz/mxKI= github.com/dlclark/regexp2 v1.11.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8= +github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc= +github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ= +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/v5 v5.12.0 h1:7Md+ndsjrzZxbddRDZjF14qK+NN56sy6wkqaVrjZtys= +github.com/go-git/go-git/v5 v5.12.0/go.mod h1:FTM9VKtnI2m65hNI/TenDDDnUf2Q9FHnXYjuz9i5OEY= +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/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM= github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg= +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/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/klauspost/compress v1.13.4/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= github.com/klauspost/compress v1.13.5/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +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/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8= +github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4= +github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/skeema/knownhosts v1.2.2 h1:Iug2P4fLmDw9f41PB6thxUkNUkJzB5i+1/exaj40L3A= +github.com/skeema/knownhosts v1.2.2/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/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fasthttp v1.30.0/go.mod h1:2rsYD01CKFrjjsvFxx75KlEUNpWNBY9JWD3K/7o2Cus= github.com/valyala/quicktemplate v1.7.0 h1:LUPTJmlVcb46OOUY3IeD9DojFpAVbsG+5WFTcjMJzCM= github.com/valyala/quicktemplate v1.7.0/go.mod h1:sqKJnoaOF88V07vkO+9FL8fb9uZg/VPSJnLYn+LmLk8= github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc= +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/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +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.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= +golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.8.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-20210510120150-4163338589ed/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +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.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.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= +golang.org/x/net v0.22.0 h1:9sGLhx7iRIHEiX0oAJ3MRZMUCElJgy7Br1nO+AMN3Tc= +golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= +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/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +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-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-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/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.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.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= +golang.org/x/sys v0.18.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.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/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= +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/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.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +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/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.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/main.go b/main.go index 0ba2dbc..644b96c 100644 --- a/main.go +++ b/main.go @@ -9,6 +9,8 @@ import ( "os/signal" "time" + "git.gabrielgio.me/cerrado/pkg/config" + "git.gabrielgio.me/cerrado/pkg/git" "git.gabrielgio.me/cerrado/pkg/handler" "git.gabrielgio.me/cerrado/pkg/service" "git.gabrielgio.me/cerrado/pkg/worker" @@ -38,8 +40,21 @@ func run(ctx context.Context) error { return err } + f, err := os.Open(*configPath) + if err != nil { + return err + } + + config, err := config.Parse(f) + if err != nil { + return err + } + + // repositories + gitServer := git.NewGitServerRepository(config.Scan.Path) + // services - gitService := service.NewGitService() + gitService := service.NewGitService(gitServer) //handlers gitHandler := handler.NewGitHandler(gitService) diff --git a/pkg/git/git.go b/pkg/git/git.go new file mode 100644 index 0000000..85a3b95 --- /dev/null +++ b/pkg/git/git.go @@ -0,0 +1,82 @@ +package git + +import ( + "errors" + "os" + "path" + + "git.gabrielgio.me/cerrado/pkg/u" + "github.com/go-git/go-git/v5" + "github.com/go-git/go-git/v5/plumbing/object" +) + +var ( + ScanPathErr = errors.New("Scan path does not exist") + RepoPathErr = errors.New("Repository path does not exist") + missingHeadErr = errors.New("Head not found") +) + +type ( + GitServerRepository struct { + scanPath string + } + + GitRepository struct { + path string + } +) + +func NewGitServerRepository(scanPath string) *GitServerRepository { + return &GitServerRepository{scanPath} +} + +func NewGitRepository(dir string) *GitRepository { + return &GitRepository{ + path: dir, + } +} + +func (g *GitServerRepository) List() ([]*GitRepository, error) { + if !u.FileExist(g.scanPath) { + return nil, ScanPathErr + } + + entries, err := os.ReadDir(g.scanPath) + if err != nil { + return nil, err + } + + repos := make([]*GitRepository, 0) + for _, e := range entries { + if !e.IsDir() { + continue + } + + fullPath := path.Join(g.scanPath, e.Name()) + repos = append(repos, NewGitRepository(fullPath)) + } + + return repos, nil +} + +func (g *GitRepository) Path() string { + return g.path +} + +func (g *GitRepository) LastCommit() (*object.Commit, error) { + repo, err := git.PlainOpen(g.path) + if err != nil { + return nil, err + } + + ref, err := repo.Head() + if err != nil { + return nil, errors.Join(missingHeadErr, err) + } + + c, err := repo.CommitObject(ref.Hash()) + if err != nil { + return nil, err + } + return c, nil +} diff --git a/pkg/handler/git.go b/pkg/handler/git.go index 5b09121..1ed2c49 100644 --- a/pkg/handler/git.go +++ b/pkg/handler/git.go @@ -1,6 +1,7 @@ package handler import ( + "log/slog" "net/http" "git.gabrielgio.me/cerrado/pkg/service" @@ -16,6 +17,12 @@ func NewGitHandler(gitService *service.GitService) *GitHandler { } func (g *GitHandler) List(w http.ResponseWriter, _ *http.Request) { - gitList := &templates.GitListPage{g.gitService.ListRepositories()} + repos, err := g.gitService.ListRepositories() + if err != nil { + slog.Error("Error listing repo", "error", err) + return + } + + gitList := &templates.GitListPage{repos} templates.WritePageTemplate(w, gitList) } diff --git a/pkg/handler/status.go b/pkg/handler/status.go index 2a84a7e..1ca7f70 100644 --- a/pkg/handler/status.go +++ b/pkg/handler/status.go @@ -19,7 +19,7 @@ func ConfigFile(configPath string) func(http.ResponseWriter, *http.Request) { return func(w http.ResponseWriter, _ *http.Request) { f, err := os.Open(configPath) if err != nil { - slog.Error("Error openning config file json", "error", err, "path", configPath) + slog.Error("Error openning config file", "error", err, "path", configPath) return } diff --git a/pkg/service/git.go b/pkg/service/git.go index 0415cee..94ca75e 100644 --- a/pkg/service/git.go +++ b/pkg/service/git.go @@ -1,30 +1,53 @@ package service -import "fmt" +import ( + "path" + + "git.gabrielgio.me/cerrado/pkg/git" +) type ( - GitService struct{} + GitService struct { + server *git.GitServerRepository + } Repository struct { - Name string - Title string - Description string + Name string + Title string + LastCommitMessage string + LastCommitDate string } ) -func NewGitService() *GitService { - return &GitService{} +// TODO: make it configurable +const timeFormat = "2006.01.02 15:04:05" + +func NewGitService(server *git.GitServerRepository) *GitService { + return &GitService{ + server: server, + } } -func (g *GitService) ListRepositories() []*Repository { - repos := make([]*Repository, 10) +func (g *GitService) ListRepositories() ([]*Repository, error) { + rs, err := g.server.List() + if err != nil { + return nil, err + } + + repos := make([]*Repository, len(rs)) + for i, r := range rs { + obj, err := r.LastCommit() + if err != nil { + return nil, err + } - for i := range 10 { + baseName := path.Base(r.Path()) repos[i] = &Repository{ - Name: fmt.Sprintf("repository-%d", i), - Title: fmt.Sprintf("Repository %d", i), - Description: fmt.Sprintf("This is a description for repository %d", i), + Name: baseName, + Title: baseName, + LastCommitMessage: obj.Message, + LastCommitDate: obj.Author.When.Format(timeFormat), } } - return repos + return repos, nil } diff --git a/pkg/u/file.go b/pkg/u/file.go new file mode 100644 index 0000000..cf86c75 --- /dev/null +++ b/pkg/u/file.go @@ -0,0 +1,21 @@ +package u + +import ( + "errors" + "log/slog" + "os" +) + +func FileExist(filename string) bool { + if _, err := os.Stat(filename); err == nil { + return true + + } else if errors.Is(err, os.ErrNotExist) { + return false + } else { + slog.Warn("Schrödinger's file: it may or may not exist", "file", filename) + // Schrodinger: file may or may not exist. To be extra safe it will + // report the file doest not exist + return false + } +} diff --git a/pkg/u/list.go b/pkg/u/list.go new file mode 100644 index 0000000..34eafd1 --- /dev/null +++ b/pkg/u/list.go @@ -0,0 +1,17 @@ +package u + +func First[T any](v []T) (T, bool) { + if len(v) == 0 { + var zero T + return zero, false + } + return v[0], true +} + +func ChunkBy[T any](items []T, chunkSize int) [][]T { + var chunks = make([][]T, 0, (len(items)/chunkSize)+1) + for chunkSize < len(items) { + items, chunks = items[chunkSize:], append(chunks, items[0:chunkSize:chunkSize]) + } + return append(chunks, items) +} diff --git a/pkg/u/list_test.go b/pkg/u/list_test.go new file mode 100644 index 0000000..a6d84c7 --- /dev/null +++ b/pkg/u/list_test.go @@ -0,0 +1,96 @@ +// go:build unit + +package u + +import ( + "testing" + + "github.com/google/go-cmp/cmp" +) + +func TestFirst(t *testing.T) { + testCases := []struct { + name string + slice []int + first int + exist bool + }{ + { + name: "multiple items slice", + slice: []int{1, 2, 3}, + first: 1, + exist: true, + }, + { + name: "single item slice", + slice: []int{1}, + first: 1, + exist: true, + }, + { + name: "empty slice", + slice: []int{}, + first: 0, + exist: false, + }, + } + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + + first, empty := First(tc.slice) + + if first != tc.first { + t.Errorf("Error first, want %d got %d", tc.first, first) + } + + if empty != tc.exist { + t.Errorf("Error empty, want %t got %t", tc.exist, empty) + } + + }) + } +} + +func TestSubList(t *testing.T) { + testCases := []struct { + name string + slice []int + size int + want [][]int + }{ + { + name: "sigle size sub list", + slice: []int{1, 2, 3}, + size: 1, + want: [][]int{{1}, {2}, {3}}, + }, + { + name: "multiple size sub list", + slice: []int{1, 2, 3, 4}, + size: 2, + want: [][]int{{1, 2}, {3, 4}}, + }, + { + name: "uneven multiple size sub list", + slice: []int{1, 2, 3, 4, 5}, + size: 2, + want: [][]int{{1, 2}, {3, 4}, {5}}, + }, + { + name: "empty sub list", + slice: []int{}, + size: 2, + want: [][]int{{}}, + }, + } + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + + subList := ChunkBy(tc.slice, tc.size) + + if diff := cmp.Diff(tc.want, subList); diff != "" { + t.Errorf("Wrong result given - wanted + got\n %s", diff) + } + }) + } +} diff --git a/pkg/u/util.go b/pkg/u/util.go deleted file mode 100644 index 34eafd1..0000000 --- a/pkg/u/util.go +++ /dev/null @@ -1,17 +0,0 @@ -package u - -func First[T any](v []T) (T, bool) { - if len(v) == 0 { - var zero T - return zero, false - } - return v[0], true -} - -func ChunkBy[T any](items []T, chunkSize int) [][]T { - var chunks = make([][]T, 0, (len(items)/chunkSize)+1) - for chunkSize < len(items) { - items, chunks = items[chunkSize:], append(chunks, items[0:chunkSize:chunkSize]) - } - return append(chunks, items) -} diff --git a/pkg/u/util_test.go b/pkg/u/util_test.go deleted file mode 100644 index a6d84c7..0000000 --- a/pkg/u/util_test.go +++ /dev/null @@ -1,96 +0,0 @@ -// go:build unit - -package u - -import ( - "testing" - - "github.com/google/go-cmp/cmp" -) - -func TestFirst(t *testing.T) { - testCases := []struct { - name string - slice []int - first int - exist bool - }{ - { - name: "multiple items slice", - slice: []int{1, 2, 3}, - first: 1, - exist: true, - }, - { - name: "single item slice", - slice: []int{1}, - first: 1, - exist: true, - }, - { - name: "empty slice", - slice: []int{}, - first: 0, - exist: false, - }, - } - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - - first, empty := First(tc.slice) - - if first != tc.first { - t.Errorf("Error first, want %d got %d", tc.first, first) - } - - if empty != tc.exist { - t.Errorf("Error empty, want %t got %t", tc.exist, empty) - } - - }) - } -} - -func TestSubList(t *testing.T) { - testCases := []struct { - name string - slice []int - size int - want [][]int - }{ - { - name: "sigle size sub list", - slice: []int{1, 2, 3}, - size: 1, - want: [][]int{{1}, {2}, {3}}, - }, - { - name: "multiple size sub list", - slice: []int{1, 2, 3, 4}, - size: 2, - want: [][]int{{1, 2}, {3, 4}}, - }, - { - name: "uneven multiple size sub list", - slice: []int{1, 2, 3, 4, 5}, - size: 2, - want: [][]int{{1, 2}, {3, 4}, {5}}, - }, - { - name: "empty sub list", - slice: []int{}, - size: 2, - want: [][]int{{}}, - }, - } - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - - subList := ChunkBy(tc.slice, tc.size) - - if diff := cmp.Diff(tc.want, subList); diff != "" { - t.Errorf("Wrong result given - wanted + got\n %s", diff) - } - }) - } -} diff --git a/scss/main.scss b/scss/main.scss index eb8a6fe..26218e8 100644 --- a/scss/main.scss +++ b/scss/main.scss @@ -1,7 +1,8 @@ //$card-border-width: 0; $card-border-radius: 0; $card-cap-padding-y: 0; -$card-cap-padding-x: 0; +$card-cap-padding-x: 5px; +$card-group-margin: 10 px; // basic functionality @import "bootstrap/scss/_functions.scss"; @@ -24,3 +25,7 @@ body { font-family: $font-family-monospace; margin: 0; } + +.card-body { + padding: 5px; +} diff --git a/templates/base.qtpl b/templates/base.qtpl index 6bef986..df6c6fc 100644 --- a/templates/base.qtpl +++ b/templates/base.qtpl @@ -25,6 +25,7 @@ Page prints a page implementing Page interface. + cerrado | {%= p.Title() %} diff --git a/templates/base.qtpl.go b/templates/base.qtpl.go index ffee940..f78744d 100644 --- a/templates/base.qtpl.go +++ b/templates/base.qtpl.go @@ -63,10 +63,11 @@ func StreamPageTemplate(qw422016 *qt422016.Writer, p Page) { + cerrado | `) -//line base.qtpl:28 +//line base.qtpl:29 p.StreamTitle(qw422016) -//line base.qtpl:28 +//line base.qtpl:29 qw422016.N().S(` @@ -84,108 +85,75 @@ func StreamPageTemplate(qw422016 *qt422016.Writer, p Page) {
`) -//line base.qtpl:44 +//line base.qtpl:45 p.StreamContent(qw422016) -//line base.qtpl:44 +//line base.qtpl:45 qw422016.N().S(`
`) -//line base.qtpl:47 +//line base.qtpl:48 p.StreamScript(qw422016) -//line base.qtpl:47 +//line base.qtpl:48 qw422016.N().S(` `) -//line base.qtpl:49 +//line base.qtpl:50 } -//line base.qtpl:49 +//line base.qtpl:50 func WritePageTemplate(qq422016 qtio422016.Writer, p Page) { -//line base.qtpl:49 +//line base.qtpl:50 qw422016 := qt422016.AcquireWriter(qq422016) -//line base.qtpl:49 +//line base.qtpl:50 StreamPageTemplate(qw422016, p) -//line base.qtpl:49 +//line base.qtpl:50 qt422016.ReleaseWriter(qw422016) -//line base.qtpl:49 +//line base.qtpl:50 } -//line base.qtpl:49 +//line base.qtpl:50 func PageTemplate(p Page) string { -//line base.qtpl:49 +//line base.qtpl:50 qb422016 := qt422016.AcquireByteBuffer() -//line base.qtpl:49 +//line base.qtpl:50 WritePageTemplate(qb422016, p) -//line base.qtpl:49 +//line base.qtpl:50 qs422016 := string(qb422016.B) -//line base.qtpl:49 +//line base.qtpl:50 qt422016.ReleaseByteBuffer(qb422016) -//line base.qtpl:49 +//line base.qtpl:50 return qs422016 -//line base.qtpl:49 +//line base.qtpl:50 } -//line base.qtpl:51 -type BasePage struct{} - -//line base.qtpl:52 -func (p *BasePage) StreamTitle(qw422016 *qt422016.Writer) { -//line base.qtpl:52 - qw422016.N().S(`Empty`) -//line base.qtpl:52 -} - -//line base.qtpl:52 -func (p *BasePage) WriteTitle(qq422016 qtio422016.Writer) { -//line base.qtpl:52 - qw422016 := qt422016.AcquireWriter(qq422016) -//line base.qtpl:52 - p.StreamTitle(qw422016) -//line base.qtpl:52 - qt422016.ReleaseWriter(qw422016) -//line base.qtpl:52 -} - -//line base.qtpl:52 -func (p *BasePage) Title() string { -//line base.qtpl:52 - qb422016 := qt422016.AcquireByteBuffer() //line base.qtpl:52 - p.WriteTitle(qb422016) -//line base.qtpl:52 - qs422016 := string(qb422016.B) -//line base.qtpl:52 - qt422016.ReleaseByteBuffer(qb422016) -//line base.qtpl:52 - return qs422016 -//line base.qtpl:52 -} +type BasePage struct{} //line base.qtpl:53 -func (p *BasePage) StreamBody(qw422016 *qt422016.Writer) { +func (p *BasePage) StreamTitle(qw422016 *qt422016.Writer) { //line base.qtpl:53 - qw422016.N().S(`HelloWorld`) + qw422016.N().S(`Empty`) //line base.qtpl:53 } //line base.qtpl:53 -func (p *BasePage) WriteBody(qq422016 qtio422016.Writer) { +func (p *BasePage) WriteTitle(qq422016 qtio422016.Writer) { //line base.qtpl:53 qw422016 := qt422016.AcquireWriter(qq422016) //line base.qtpl:53 - p.StreamBody(qw422016) + p.StreamTitle(qw422016) //line base.qtpl:53 qt422016.ReleaseWriter(qw422016) //line base.qtpl:53 } //line base.qtpl:53 -func (p *BasePage) Body() string { +func (p *BasePage) Title() string { //line base.qtpl:53 qb422016 := qt422016.AcquireByteBuffer() //line base.qtpl:53 - p.WriteBody(qb422016) + p.WriteTitle(qb422016) //line base.qtpl:53 qs422016 := string(qb422016.B) //line base.qtpl:53 @@ -196,27 +164,29 @@ func (p *BasePage) Body() string { } //line base.qtpl:54 -func (p *BasePage) StreamScript(qw422016 *qt422016.Writer) { +func (p *BasePage) StreamBody(qw422016 *qt422016.Writer) { +//line base.qtpl:54 + qw422016.N().S(`HelloWorld`) //line base.qtpl:54 } //line base.qtpl:54 -func (p *BasePage) WriteScript(qq422016 qtio422016.Writer) { +func (p *BasePage) WriteBody(qq422016 qtio422016.Writer) { //line base.qtpl:54 qw422016 := qt422016.AcquireWriter(qq422016) //line base.qtpl:54 - p.StreamScript(qw422016) + p.StreamBody(qw422016) //line base.qtpl:54 qt422016.ReleaseWriter(qw422016) //line base.qtpl:54 } //line base.qtpl:54 -func (p *BasePage) Script() string { +func (p *BasePage) Body() string { //line base.qtpl:54 qb422016 := qt422016.AcquireByteBuffer() //line base.qtpl:54 - p.WriteScript(qb422016) + p.WriteBody(qb422016) //line base.qtpl:54 qs422016 := string(qb422016.B) //line base.qtpl:54 @@ -225,3 +195,34 @@ func (p *BasePage) Script() string { return qs422016 //line base.qtpl:54 } + +//line base.qtpl:55 +func (p *BasePage) StreamScript(qw422016 *qt422016.Writer) { +//line base.qtpl:55 +} + +//line base.qtpl:55 +func (p *BasePage) WriteScript(qq422016 qtio422016.Writer) { +//line base.qtpl:55 + qw422016 := qt422016.AcquireWriter(qq422016) +//line base.qtpl:55 + p.StreamScript(qw422016) +//line base.qtpl:55 + qt422016.ReleaseWriter(qw422016) +//line base.qtpl:55 +} + +//line base.qtpl:55 +func (p *BasePage) Script() string { +//line base.qtpl:55 + qb422016 := qt422016.AcquireByteBuffer() +//line base.qtpl:55 + p.WriteScript(qb422016) +//line base.qtpl:55 + qs422016 := string(qb422016.B) +//line base.qtpl:55 + qt422016.ReleaseByteBuffer(qb422016) +//line base.qtpl:55 + return qs422016 +//line base.qtpl:55 +} diff --git a/templates/gitlist.qtpl b/templates/gitlist.qtpl index 10a89da..84a42f9 100644 --- a/templates/gitlist.qtpl +++ b/templates/gitlist.qtpl @@ -14,14 +14,17 @@ type GitListPage struct { {% for _, c := range u.ChunkBy(p.Respositories, 3) %}
{% for _, r := range c %} -
+
- {%s r.Title %} + {%s r.Title %}
-

{%s r.Description %}

- go to repository +

{%s r.LastCommitMessage %}

+

{%s r.LastCommitDate %}

+ summary + log + tree
diff --git a/templates/gitlist.qtpl.go b/templates/gitlist.qtpl.go index b02eead..d16b8d5 100644 --- a/templates/gitlist.qtpl.go +++ b/templates/gitlist.qtpl.go @@ -76,100 +76,107 @@ func (p *GitListPage) StreamContent(qw422016 *qt422016.Writer) { for _, r := range c { //line gitlist.qtpl:16 qw422016.N().S(` -
+ `) -//line gitlist.qtpl:28 +//line gitlist.qtpl:31 } -//line gitlist.qtpl:28 +//line gitlist.qtpl:31 qw422016.N().S(`
`) -//line gitlist.qtpl:30 +//line gitlist.qtpl:33 } -//line gitlist.qtpl:30 +//line gitlist.qtpl:33 qw422016.N().S(` `) -//line gitlist.qtpl:31 +//line gitlist.qtpl:34 } -//line gitlist.qtpl:31 +//line gitlist.qtpl:34 func (p *GitListPage) WriteContent(qq422016 qtio422016.Writer) { -//line gitlist.qtpl:31 +//line gitlist.qtpl:34 qw422016 := qt422016.AcquireWriter(qq422016) -//line gitlist.qtpl:31 +//line gitlist.qtpl:34 p.StreamContent(qw422016) -//line gitlist.qtpl:31 +//line gitlist.qtpl:34 qt422016.ReleaseWriter(qw422016) -//line gitlist.qtpl:31 +//line gitlist.qtpl:34 } -//line gitlist.qtpl:31 +//line gitlist.qtpl:34 func (p *GitListPage) Content() string { -//line gitlist.qtpl:31 +//line gitlist.qtpl:34 qb422016 := qt422016.AcquireByteBuffer() -//line gitlist.qtpl:31 +//line gitlist.qtpl:34 p.WriteContent(qb422016) -//line gitlist.qtpl:31 +//line gitlist.qtpl:34 qs422016 := string(qb422016.B) -//line gitlist.qtpl:31 +//line gitlist.qtpl:34 qt422016.ReleaseByteBuffer(qb422016) -//line gitlist.qtpl:31 +//line gitlist.qtpl:34 return qs422016 -//line gitlist.qtpl:31 +//line gitlist.qtpl:34 } -//line gitlist.qtpl:33 +//line gitlist.qtpl:36 func (p *GitListPage) StreamScript(qw422016 *qt422016.Writer) { -//line gitlist.qtpl:33 +//line gitlist.qtpl:36 qw422016.N().S(` `) -//line gitlist.qtpl:34 +//line gitlist.qtpl:37 } -//line gitlist.qtpl:34 +//line gitlist.qtpl:37 func (p *GitListPage) WriteScript(qq422016 qtio422016.Writer) { -//line gitlist.qtpl:34 +//line gitlist.qtpl:37 qw422016 := qt422016.AcquireWriter(qq422016) -//line gitlist.qtpl:34 +//line gitlist.qtpl:37 p.StreamScript(qw422016) -//line gitlist.qtpl:34 +//line gitlist.qtpl:37 qt422016.ReleaseWriter(qw422016) -//line gitlist.qtpl:34 +//line gitlist.qtpl:37 } -//line gitlist.qtpl:34 +//line gitlist.qtpl:37 func (p *GitListPage) Script() string { -//line gitlist.qtpl:34 +//line gitlist.qtpl:37 qb422016 := qt422016.AcquireByteBuffer() -//line gitlist.qtpl:34 +//line gitlist.qtpl:37 p.WriteScript(qb422016) -//line gitlist.qtpl:34 +//line gitlist.qtpl:37 qs422016 := string(qb422016.B) -//line gitlist.qtpl:34 +//line gitlist.qtpl:37 qt422016.ReleaseByteBuffer(qb422016) -//line gitlist.qtpl:34 +//line gitlist.qtpl:37 return qs422016 -//line gitlist.qtpl:34 +//line gitlist.qtpl:37 } -- cgit v1.2.3