mirror of
https://github.com/thomiceli/opengist.git
synced 2024-12-22 20:42:40 +00:00
Move Git hook logic to Opengist (#213)
This commit is contained in:
parent
dfe70dc4cf
commit
7a75c5ecfa
16 changed files with 407 additions and 193 deletions
4
go.mod
4
go.mod
|
@ -17,6 +17,7 @@ require (
|
||||||
github.com/markbates/goth v1.78.0
|
github.com/markbates/goth v1.78.0
|
||||||
github.com/rs/zerolog v1.31.0
|
github.com/rs/zerolog v1.31.0
|
||||||
github.com/stretchr/testify v1.8.4
|
github.com/stretchr/testify v1.8.4
|
||||||
|
github.com/urfave/cli/v2 v2.27.1
|
||||||
github.com/yuin/goldmark v1.6.0
|
github.com/yuin/goldmark v1.6.0
|
||||||
github.com/yuin/goldmark-emoji v1.0.2
|
github.com/yuin/goldmark-emoji v1.0.2
|
||||||
github.com/yuin/goldmark-highlighting/v2 v2.0.0-20230729083705-37449abec8cc
|
github.com/yuin/goldmark-highlighting/v2 v2.0.0-20230729083705-37449abec8cc
|
||||||
|
@ -45,6 +46,7 @@ require (
|
||||||
github.com/blevesearch/zapx/v13 v13.3.10 // indirect
|
github.com/blevesearch/zapx/v13 v13.3.10 // indirect
|
||||||
github.com/blevesearch/zapx/v14 v14.3.10 // indirect
|
github.com/blevesearch/zapx/v14 v14.3.10 // indirect
|
||||||
github.com/blevesearch/zapx/v15 v15.3.13 // indirect
|
github.com/blevesearch/zapx/v15 v15.3.13 // indirect
|
||||||
|
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
|
||||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||||
github.com/dlclark/regexp2 v1.10.0 // indirect
|
github.com/dlclark/regexp2 v1.10.0 // indirect
|
||||||
github.com/gabriel-vasile/mimetype v1.4.3 // indirect
|
github.com/gabriel-vasile/mimetype v1.4.3 // indirect
|
||||||
|
@ -72,8 +74,10 @@ require (
|
||||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
|
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
|
||||||
github.com/rivo/uniseg v0.4.4 // indirect
|
github.com/rivo/uniseg v0.4.4 // indirect
|
||||||
|
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||||
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
||||||
github.com/valyala/fasttemplate v1.2.2 // indirect
|
github.com/valyala/fasttemplate v1.2.2 // indirect
|
||||||
|
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect
|
||||||
go.etcd.io/bbolt v1.3.8 // indirect
|
go.etcd.io/bbolt v1.3.8 // indirect
|
||||||
golang.org/x/net v0.19.0 // indirect
|
golang.org/x/net v0.19.0 // indirect
|
||||||
golang.org/x/oauth2 v0.15.0 // indirect
|
golang.org/x/oauth2 v0.15.0 // indirect
|
||||||
|
|
8
go.sum
8
go.sum
|
@ -94,6 +94,8 @@ github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMn
|
||||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||||
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
||||||
|
github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w=
|
||||||
|
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
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/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
@ -291,6 +293,8 @@ github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFR
|
||||||
github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
|
github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
|
||||||
github.com/rs/zerolog v1.31.0 h1:FcTR3NnLWW+NnTwwhFWiJSZr4ECLpqCm6QsEnyvbV4A=
|
github.com/rs/zerolog v1.31.0 h1:FcTR3NnLWW+NnTwwhFWiJSZr4ECLpqCm6QsEnyvbV4A=
|
||||||
github.com/rs/zerolog v1.31.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss=
|
github.com/rs/zerolog v1.31.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss=
|
||||||
|
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/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||||
|
@ -304,10 +308,14 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO
|
||||||
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||||
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||||
|
github.com/urfave/cli/v2 v2.27.1 h1:8xSQ6szndafKVRmfyeUMxkNUJQMjL1F2zmsZ+qHpfho=
|
||||||
|
github.com/urfave/cli/v2 v2.27.1/go.mod h1:8qnjx1vcq5s2/wpsqoZFndg2CE5tNFyrTvS6SinrnYQ=
|
||||||
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
|
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/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
|
||||||
github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo=
|
github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo=
|
||||||
github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
|
github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
|
||||||
|
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU=
|
||||||
|
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8=
|
||||||
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||||
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||||
|
|
|
@ -18,11 +18,11 @@ type ActionStatus struct {
|
||||||
|
|
||||||
const (
|
const (
|
||||||
SyncReposFromFS = iota
|
SyncReposFromFS = iota
|
||||||
SyncReposFromDB = iota
|
SyncReposFromDB
|
||||||
GitGcRepos = iota
|
GitGcRepos
|
||||||
SyncGistPreviews = iota
|
SyncGistPreviews
|
||||||
ResetHooks = iota
|
ResetHooks
|
||||||
IndexGists = iota
|
IndexGists
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|
38
internal/cli/hook.go
Normal file
38
internal/cli/hook.go
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
package cli
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/thomiceli/opengist/internal/hooks"
|
||||||
|
"github.com/urfave/cli/v2"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
var CmdHook = cli.Command{
|
||||||
|
Name: "hook",
|
||||||
|
Usage: "Run Git server hooks, used and should only be called by Opengist itself",
|
||||||
|
Subcommands: []*cli.Command{
|
||||||
|
&CmdHookPreReceive,
|
||||||
|
&CmdHookPostReceive,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
var CmdHookPreReceive = cli.Command{
|
||||||
|
Name: "pre-receive",
|
||||||
|
Usage: "Run Git server pre-receive hook for a repository",
|
||||||
|
Action: func(ctx *cli.Context) error {
|
||||||
|
if err := hooks.PreReceive(os.Stdin, os.Stdout, os.Stderr); err != nil {
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
var CmdHookPostReceive = cli.Command{
|
||||||
|
Name: "post-receive",
|
||||||
|
Usage: "Run Git server post-receive hook for a repository",
|
||||||
|
Action: func(ctx *cli.Context) error {
|
||||||
|
if err := hooks.PostReceive(os.Stdin, os.Stdout, os.Stderr); err != nil {
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
}
|
131
internal/cli/main.go
Normal file
131
internal/cli/main.go
Normal file
|
@ -0,0 +1,131 @@
|
||||||
|
package cli
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/rs/zerolog/log"
|
||||||
|
"github.com/thomiceli/opengist/internal/config"
|
||||||
|
"github.com/thomiceli/opengist/internal/db"
|
||||||
|
"github.com/thomiceli/opengist/internal/git"
|
||||||
|
"github.com/thomiceli/opengist/internal/index"
|
||||||
|
"github.com/thomiceli/opengist/internal/memdb"
|
||||||
|
"github.com/thomiceli/opengist/internal/ssh"
|
||||||
|
"github.com/thomiceli/opengist/internal/web"
|
||||||
|
"github.com/urfave/cli/v2"
|
||||||
|
"os"
|
||||||
|
"path"
|
||||||
|
"path/filepath"
|
||||||
|
)
|
||||||
|
|
||||||
|
var CmdVersion = cli.Command{
|
||||||
|
Name: "version",
|
||||||
|
Usage: "Print the version of Opengist",
|
||||||
|
Action: func(c *cli.Context) error {
|
||||||
|
fmt.Println("Opengist v" + config.OpengistVersion)
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
var CmdStart = cli.Command{
|
||||||
|
Name: "start",
|
||||||
|
Usage: "Start Opengist server",
|
||||||
|
Action: func(ctx *cli.Context) error {
|
||||||
|
Initialize(ctx)
|
||||||
|
go web.NewServer(os.Getenv("OG_DEV") == "1").Start()
|
||||||
|
go ssh.Start()
|
||||||
|
select {}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
var ConfigFlag = cli.StringFlag{
|
||||||
|
Name: "config",
|
||||||
|
Aliases: []string{"c"},
|
||||||
|
Usage: "Path to a config file in YAML format",
|
||||||
|
}
|
||||||
|
|
||||||
|
func App() error {
|
||||||
|
app := cli.NewApp()
|
||||||
|
app.Name = "Opengist"
|
||||||
|
app.Usage = "A self-hosted pastebin powered by Git."
|
||||||
|
app.HelpName = "opengist"
|
||||||
|
|
||||||
|
app.Commands = []*cli.Command{&CmdVersion, &CmdStart, &CmdHook}
|
||||||
|
app.DefaultCommand = CmdStart.Name
|
||||||
|
app.Flags = []cli.Flag{
|
||||||
|
&ConfigFlag,
|
||||||
|
}
|
||||||
|
return app.Run(os.Args)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Initialize(ctx *cli.Context) {
|
||||||
|
fmt.Println("Opengist v" + config.OpengistVersion)
|
||||||
|
|
||||||
|
if err := config.InitConfig(ctx.String("config")); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
if err := os.MkdirAll(filepath.Join(config.GetHomeDir()), 0755); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
config.InitLog()
|
||||||
|
|
||||||
|
gitVersion, err := git.GetGitVersion()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal().Err(err).Send()
|
||||||
|
}
|
||||||
|
|
||||||
|
if ok, err := config.CheckGitVersion(gitVersion); err != nil {
|
||||||
|
log.Fatal().Err(err).Send()
|
||||||
|
} else if !ok {
|
||||||
|
log.Warn().Msg("Git version may be too old, as Opengist has not been tested prior git version 2.28 and some features would not work. " +
|
||||||
|
"Current git version: " + gitVersion)
|
||||||
|
}
|
||||||
|
|
||||||
|
homePath := config.GetHomeDir()
|
||||||
|
log.Info().Msg("Data directory: " + homePath)
|
||||||
|
|
||||||
|
if err := createSymlink(); err != nil {
|
||||||
|
log.Fatal().Err(err).Send()
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := os.MkdirAll(filepath.Join(homePath, "repos"), 0755); err != nil {
|
||||||
|
log.Fatal().Err(err).Send()
|
||||||
|
}
|
||||||
|
if err := os.MkdirAll(filepath.Join(homePath, "tmp", "repos"), 0755); err != nil {
|
||||||
|
log.Fatal().Err(err).Send()
|
||||||
|
}
|
||||||
|
if err := os.MkdirAll(filepath.Join(homePath, "custom"), 0755); err != nil {
|
||||||
|
log.Fatal().Err(err).Send()
|
||||||
|
}
|
||||||
|
log.Info().Msg("Database file: " + filepath.Join(homePath, config.C.DBFilename))
|
||||||
|
if err := db.Setup(filepath.Join(homePath, config.C.DBFilename), false); err != nil {
|
||||||
|
log.Fatal().Err(err).Msg("Failed to initialize database")
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := memdb.Setup(); err != nil {
|
||||||
|
log.Fatal().Err(err).Msg("Failed to initialize in memory database")
|
||||||
|
}
|
||||||
|
|
||||||
|
if config.C.IndexEnabled {
|
||||||
|
log.Info().Msg("Index directory: " + filepath.Join(homePath, config.C.IndexDirname))
|
||||||
|
if err := index.Open(filepath.Join(homePath, config.C.IndexDirname)); err != nil {
|
||||||
|
log.Fatal().Err(err).Msg("Failed to open index")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func createSymlink() error {
|
||||||
|
exePath, err := os.Executable()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
symlinkPath := path.Join(config.GetHomeDir(), "opengist-bin")
|
||||||
|
|
||||||
|
if _, err := os.Lstat(symlinkPath); err == nil {
|
||||||
|
if err := os.Remove(symlinkPath); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return os.Symlink(exePath, symlinkPath)
|
||||||
|
}
|
|
@ -121,6 +121,10 @@ func InitConfig(configPath string) error {
|
||||||
|
|
||||||
C = c
|
C = c
|
||||||
|
|
||||||
|
if err = os.Setenv("OG_OPENGIST_HOME_INTERNAL", GetHomeDir()); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,6 @@ import (
|
||||||
"github.com/alecthomas/chroma/v2"
|
"github.com/alecthomas/chroma/v2"
|
||||||
"github.com/alecthomas/chroma/v2/lexers"
|
"github.com/alecthomas/chroma/v2/lexers"
|
||||||
"github.com/dustin/go-humanize"
|
"github.com/dustin/go-humanize"
|
||||||
"github.com/labstack/echo/v4"
|
|
||||||
"github.com/rs/zerolog/log"
|
"github.com/rs/zerolog/log"
|
||||||
"github.com/thomiceli/opengist/internal/index"
|
"github.com/thomiceli/opengist/internal/index"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
|
@ -330,10 +329,6 @@ func (gist *Gist) InitRepository() error {
|
||||||
return git.InitRepository(gist.User.Username, gist.Uuid)
|
return git.InitRepository(gist.User.Username, gist.Uuid)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gist *Gist) InitRepositoryViaInit(ctx echo.Context) error {
|
|
||||||
return git.InitRepositoryViaInit(gist.User.Username, gist.Uuid, ctx)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (gist *Gist) DeleteRepository() error {
|
func (gist *Gist) DeleteRepository() error {
|
||||||
return git.DeleteRepository(gist.User.Username, gist.Uuid)
|
return git.DeleteRepository(gist.User.Username, gist.Uuid)
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,7 @@ type SSHKey struct {
|
||||||
User User `validate:"-" `
|
User User `validate:"-" `
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sshKey *SSHKey) BeforeCreate(tx *gorm.DB) error {
|
func (sshKey *SSHKey) BeforeCreate(*gorm.DB) error {
|
||||||
pubKey, _, _, _, err := ssh.ParseAuthorizedKey([]byte(sshKey.Content))
|
pubKey, _, _, _, err := ssh.ParseAuthorizedKey([]byte(sshKey.Content))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -24,6 +24,7 @@ var (
|
||||||
)
|
)
|
||||||
|
|
||||||
const truncateLimit = 2 << 18
|
const truncateLimit = 2 << 18
|
||||||
|
const BaseHash = "0000000000000000000000000000000000000000"
|
||||||
|
|
||||||
type RevisionNotFoundError struct{}
|
type RevisionNotFoundError struct{}
|
||||||
|
|
||||||
|
@ -80,16 +81,6 @@ func InitRepository(user string, gist string) error {
|
||||||
return CreateDotGitFiles(user, gist)
|
return CreateDotGitFiles(user, gist)
|
||||||
}
|
}
|
||||||
|
|
||||||
func InitRepositoryViaInit(user string, gist string, ctx echo.Context) error {
|
|
||||||
repositoryPath := RepositoryPath(user, gist)
|
|
||||||
|
|
||||||
if err := InitRepository(user, gist); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
repositoryUrl := RepositoryUrl(ctx, user, gist)
|
|
||||||
return createDotGitHookFile(repositoryPath, "post-receive", fmt.Sprintf(postReceive, repositoryUrl, repositoryUrl))
|
|
||||||
}
|
|
||||||
|
|
||||||
func CountCommits(user string, gist string) (string, error) {
|
func CountCommits(user string, gist string) (string, error) {
|
||||||
repositoryPath := RepositoryPath(user, gist)
|
repositoryPath := RepositoryPath(user, gist)
|
||||||
|
|
||||||
|
@ -424,7 +415,6 @@ func Push(gistTmpId string) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return os.RemoveAll(tmpRepositoryPath)
|
return os.RemoveAll(tmpRepositoryPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -534,9 +524,13 @@ func CreateDotGitFiles(user string, gist string) error {
|
||||||
}
|
}
|
||||||
defer f1.Close()
|
defer f1.Close()
|
||||||
|
|
||||||
if err = createDotGitHookFile(repositoryPath, "pre-receive", preReceive); err != nil {
|
if os.Getenv("OPENGIST_SKIP_GIT_HOOKS") != "1" {
|
||||||
|
for _, hook := range []string{"pre-receive", "post-receive"} {
|
||||||
|
if err = createDotGitHookFile(repositoryPath, hook, fmt.Sprintf(hookTemplate, hook)); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -570,57 +564,6 @@ func removeFilesExceptGit(dir string) error {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const preReceive = `#!/bin/sh
|
const hookTemplate = `#!/bin/sh
|
||||||
|
"$OG_OPENGIST_HOME_INTERNAL/opengist-bin" hook %s
|
||||||
disallowed_files=""
|
|
||||||
|
|
||||||
while read -r old_rev new_rev ref
|
|
||||||
do
|
|
||||||
if [ "$old_rev" = "0000000000000000000000000000000000000000" ]; then
|
|
||||||
# This is the first commit, so we check all the files in that commit
|
|
||||||
changed_files=$(git ls-tree -r --name-only "$new_rev")
|
|
||||||
else
|
|
||||||
# This is not the first commit, so we compare it with its predecessor
|
|
||||||
changed_files=$(git diff --name-only "$old_rev" "$new_rev")
|
|
||||||
fi
|
|
||||||
|
|
||||||
while IFS= read -r file
|
|
||||||
do
|
|
||||||
case $file in
|
|
||||||
*/*)
|
|
||||||
disallowed_files="${disallowed_files}${file} "
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
done <<EOF
|
|
||||||
$changed_files
|
|
||||||
EOF
|
|
||||||
done
|
|
||||||
|
|
||||||
if [ -n "$disallowed_files" ]; then
|
|
||||||
echo ""
|
|
||||||
echo "Pushing files in folders is not allowed:"
|
|
||||||
for file in $disallowed_files; do
|
|
||||||
echo " $file"
|
|
||||||
done
|
|
||||||
echo ""
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
`
|
|
||||||
|
|
||||||
const postReceive = `#!/bin/sh
|
|
||||||
|
|
||||||
while read oldrev newrev refname; do
|
|
||||||
if ! git rev-parse --verify --quiet HEAD &>/dev/null; then
|
|
||||||
git symbolic-ref HEAD "$refname"
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "Your new repository has been created here: %s"
|
|
||||||
echo ""
|
|
||||||
echo "If you want to keep working with your gist, you could set the remote URL via:"
|
|
||||||
echo "git remote set-url origin %s"
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
rm -f $0
|
|
||||||
`
|
`
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
package git
|
package git
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/labstack/echo/v4"
|
"bytes"
|
||||||
|
"fmt"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
"github.com/thomiceli/opengist/internal/config"
|
"github.com/thomiceli/opengist/internal/config"
|
||||||
"net/http"
|
"github.com/thomiceli/opengist/internal/hooks"
|
||||||
"net/http/httptest"
|
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"path"
|
"path"
|
||||||
|
@ -15,6 +15,8 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func setup(t *testing.T) {
|
func setup(t *testing.T) {
|
||||||
|
_ = os.Setenv("OPENGIST_SKIP_GIT_HOOKS", "1")
|
||||||
|
|
||||||
err := config.InitConfig("")
|
err := config.InitConfig("")
|
||||||
require.NoError(t, err, "Could not init config")
|
require.NoError(t, err, "Could not init config")
|
||||||
|
|
||||||
|
@ -30,7 +32,7 @@ func setup(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func teardown(t *testing.T) {
|
func teardown(t *testing.T) {
|
||||||
err := os.RemoveAll(path.Join(config.C.OpengistHome, "tests"))
|
err := os.RemoveAll(path.Join(config.GetHomeDir(), "tests"))
|
||||||
require.NoError(t, err, "Could not remove repos directory")
|
require.NoError(t, err, "Could not remove repos directory")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,9 +46,6 @@ func TestInitDeleteRepository(t *testing.T) {
|
||||||
require.NoError(t, err, "Could not run git command")
|
require.NoError(t, err, "Could not run git command")
|
||||||
require.Equal(t, "true", strings.TrimSpace(string(out)), "Repository is not bare")
|
require.Equal(t, "true", strings.TrimSpace(string(out)), "Repository is not bare")
|
||||||
|
|
||||||
_, err = os.Stat(path.Join(RepositoryPath("thomas", "gist1"), "hooks", "pre-receive"))
|
|
||||||
require.NoError(t, err, "pre-receive hook not found")
|
|
||||||
|
|
||||||
_, err = os.Stat(path.Join(RepositoryPath("thomas", "gist1"), "git-daemon-export-ok"))
|
_, err = os.Stat(path.Join(RepositoryPath("thomas", "gist1"), "git-daemon-export-ok"))
|
||||||
require.NoError(t, err, "git-daemon-export-ok file not found")
|
require.NoError(t, err, "git-daemon-export-ok file not found")
|
||||||
|
|
||||||
|
@ -247,30 +246,6 @@ func TestTruncate(t *testing.T) {
|
||||||
require.Equal(t, 2, len(content), "Content size is not correct")
|
require.Equal(t, 2, len(content), "Content size is not correct")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestInitViaGitInit(t *testing.T) {
|
|
||||||
setup(t)
|
|
||||||
defer teardown(t)
|
|
||||||
|
|
||||||
e := echo.New()
|
|
||||||
|
|
||||||
// Create a mock HTTP request
|
|
||||||
req := httptest.NewRequest(http.MethodPost, "/", nil)
|
|
||||||
|
|
||||||
// Create a mock HTTP response recorder
|
|
||||||
rec := httptest.NewRecorder()
|
|
||||||
|
|
||||||
// Create a new Echo context
|
|
||||||
c := e.NewContext(req, rec)
|
|
||||||
|
|
||||||
// Define your user and gist
|
|
||||||
user := "testUser"
|
|
||||||
gist := "testGist"
|
|
||||||
|
|
||||||
err := InitRepositoryViaInit(user, gist, c)
|
|
||||||
|
|
||||||
require.NoError(t, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestGitInitBranchNames(t *testing.T) {
|
func TestGitInitBranchNames(t *testing.T) {
|
||||||
setup(t)
|
setup(t)
|
||||||
defer teardown(t)
|
defer teardown(t)
|
||||||
|
@ -292,21 +267,67 @@ func TestGitInitBranchNames(t *testing.T) {
|
||||||
require.Equal(t, "refs/heads/main", strings.TrimSpace(string(out)), "Repository should have main branch as default")
|
require.Equal(t, "refs/heads/main", strings.TrimSpace(string(out)), "Repository should have main branch as default")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestPreReceiveHook(t *testing.T) {
|
||||||
|
setup(t)
|
||||||
|
defer teardown(t)
|
||||||
|
var lastCommitHash string
|
||||||
|
err := os.Chdir(RepositoryPath("thomas", "gist1"))
|
||||||
|
require.NoError(t, err, "Could not change directory")
|
||||||
|
|
||||||
|
commitToBare(t, "thomas", "gist1", map[string]string{
|
||||||
|
"my_file.txt": "some allowed file",
|
||||||
|
"my_file2.txt": "some allowed file\nagain",
|
||||||
|
})
|
||||||
|
lastCommitHash = lastHashOfCommit(t, "thomas", "gist1")
|
||||||
|
err = hooks.PreReceive(bytes.NewBufferString(fmt.Sprintf("%s %s %s", BaseHash, lastCommitHash, "refs/heads/master")), os.Stdout, os.Stderr)
|
||||||
|
require.NoError(t, err, "Should not have an error on pre-receive hook for commit+push 1")
|
||||||
|
|
||||||
|
commitToBare(t, "thomas", "gist1", map[string]string{
|
||||||
|
"my_file.txt": "some allowed file",
|
||||||
|
"dir/my_file.txt": "some disallowed file suddenly",
|
||||||
|
})
|
||||||
|
lastCommitHash = lastHashOfCommit(t, "thomas", "gist1")
|
||||||
|
err = hooks.PreReceive(bytes.NewBufferString(fmt.Sprintf("%s %s %s", BaseHash, lastCommitHash, "refs/heads/master")), os.Stdout, os.Stderr)
|
||||||
|
require.Error(t, err, "Should have an error on pre-receive hook for commit+push 2")
|
||||||
|
require.Equal(t, "pushing files in directories is not allowed: [dir/my_file.txt]", err.Error(), "Error message is not correct")
|
||||||
|
|
||||||
|
commitToBare(t, "thomas", "gist1", map[string]string{
|
||||||
|
"my_file.txt": "some allowed file",
|
||||||
|
"dir/ok/afileagain.txt": "some disallowed file\nagain",
|
||||||
|
})
|
||||||
|
lastCommitHash = lastHashOfCommit(t, "thomas", "gist1")
|
||||||
|
err = hooks.PreReceive(bytes.NewBufferString(fmt.Sprintf("%s %s %s", BaseHash, lastCommitHash, "refs/heads/master")), os.Stdout, os.Stderr)
|
||||||
|
require.Error(t, err, "Should have an error on pre-receive hook for commit+push 3")
|
||||||
|
require.Equal(t, "pushing files in directories is not allowed: [dir/ok/afileagain.txt dir/my_file.txt]", err.Error(), "Error message is not correct")
|
||||||
|
|
||||||
|
commitToBare(t, "thomas", "gist1", map[string]string{
|
||||||
|
"allowedfile.txt": "some allowed file only",
|
||||||
|
})
|
||||||
|
lastCommitHash = lastHashOfCommit(t, "thomas", "gist1")
|
||||||
|
err = hooks.PreReceive(bytes.NewBufferString(fmt.Sprintf("%s %s %s", BaseHash, lastCommitHash, "refs/heads/master")), os.Stdout, os.Stderr)
|
||||||
|
require.Error(t, err, "Should have an error on pre-receive hook for commit+push 4")
|
||||||
|
require.Equal(t, "pushing files in directories is not allowed: [dir/ok/afileagain.txt dir/my_file.txt]", err.Error(), "Error message is not correct")
|
||||||
|
|
||||||
|
_ = os.Chdir(os.TempDir()) // Leave the current dir to avoid errors on teardown
|
||||||
|
}
|
||||||
|
|
||||||
func commitToBare(t *testing.T, user string, gist string, files map[string]string) {
|
func commitToBare(t *testing.T, user string, gist string, files map[string]string) {
|
||||||
err := CloneTmp(user, gist, gist, "thomas@mail.com", true)
|
err := CloneTmp(user, gist, gist, "thomas@mail.com", true)
|
||||||
require.NoError(t, err, "Could not commit to repository")
|
require.NoError(t, err, "Could not clone repository")
|
||||||
|
|
||||||
if len(files) > 0 {
|
if len(files) > 0 {
|
||||||
for filename, content := range files {
|
for filename, content := range files {
|
||||||
if err := SetFileContent(gist, filename, content); err != nil {
|
if strings.Contains(filename, "/") {
|
||||||
require.NoError(t, err, "Could not commit to repository")
|
dir := filepath.Dir(filename)
|
||||||
|
err := os.MkdirAll(filepath.Join(TmpRepositoryPath(gist), dir), os.ModePerm)
|
||||||
|
require.NoError(t, err, "Could not create directory")
|
||||||
}
|
}
|
||||||
|
_ = os.WriteFile(filepath.Join(TmpRepositoryPath(gist), filename), []byte(content), 0644)
|
||||||
|
|
||||||
if err := AddAll(gist); err != nil {
|
if err := AddAll(gist); err != nil {
|
||||||
require.NoError(t, err, "Could not commit to repository")
|
require.NoError(t, err, "Could not add all to repository")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := CommitRepository(gist, user, "thomas@mail.com"); err != nil {
|
if err := CommitRepository(gist, user, "thomas@mail.com"); err != nil {
|
||||||
|
@ -314,6 +335,14 @@ func commitToBare(t *testing.T, user string, gist string, files map[string]strin
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := Push(gist); err != nil {
|
if err := Push(gist); err != nil {
|
||||||
require.NoError(t, err, "Could not commit to repository")
|
require.NoError(t, err, "Could not push to repository")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func lastHashOfCommit(t *testing.T, user string, gist string) string {
|
||||||
|
cmd := exec.Command("git", "rev-parse", "HEAD")
|
||||||
|
cmd.Dir = RepositoryPath(user, gist)
|
||||||
|
out, err := cmd.Output()
|
||||||
|
require.NoError(t, err, "Could not run git command")
|
||||||
|
return strings.TrimSpace(string(out))
|
||||||
|
}
|
||||||
|
|
43
internal/hooks/post-receive.go
Normal file
43
internal/hooks/post-receive.go
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
package hooks
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
func PostReceive(in io.Reader, out, er io.Writer) error {
|
||||||
|
scanner := bufio.NewScanner(in)
|
||||||
|
for scanner.Scan() {
|
||||||
|
line := scanner.Text()
|
||||||
|
parts := strings.Fields(line)
|
||||||
|
if len(parts) != 3 {
|
||||||
|
_, _ = fmt.Fprintln(er, "Invalid input")
|
||||||
|
return fmt.Errorf("invalid input")
|
||||||
|
}
|
||||||
|
oldrev, _, refname := parts[0], parts[1], parts[2]
|
||||||
|
|
||||||
|
if err := verifyHEAD(); err != nil {
|
||||||
|
setSymbolicRef(refname)
|
||||||
|
}
|
||||||
|
|
||||||
|
if oldrev == BaseHash {
|
||||||
|
_, _ = fmt.Fprintf(out, "\nYour new repository has been created here: %s\n\n", os.Getenv("OPENGIST_REPOSITORY_URL_INTERNAL"))
|
||||||
|
_, _ = fmt.Fprintln(out, "If you want to keep working with your gist, you could set the remote URL via:")
|
||||||
|
_, _ = fmt.Fprintf(out, "git remote set-url origin %s\n\n", os.Getenv("OPENGIST_REPOSITORY_URL_INTERNAL"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func verifyHEAD() error {
|
||||||
|
return exec.Command("git", "rev-parse", "--verify", "--quiet", "HEAD").Run()
|
||||||
|
}
|
||||||
|
|
||||||
|
func setSymbolicRef(refname string) {
|
||||||
|
_ = exec.Command("git", "symbolic-ref", "HEAD", refname).Run()
|
||||||
|
}
|
80
internal/hooks/pre-receive.go
Normal file
80
internal/hooks/pre-receive.go
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
package hooks
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"os/exec"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
const BaseHash = "0000000000000000000000000000000000000000"
|
||||||
|
|
||||||
|
func PreReceive(in io.Reader, out, er io.Writer) error {
|
||||||
|
var err error
|
||||||
|
var disallowedFiles []string
|
||||||
|
var disallowedCommits []string
|
||||||
|
|
||||||
|
scanner := bufio.NewScanner(in)
|
||||||
|
for scanner.Scan() {
|
||||||
|
line := scanner.Text()
|
||||||
|
parts := strings.Split(line, " ")
|
||||||
|
if len(parts) < 3 {
|
||||||
|
_, _ = fmt.Fprintln(er, "Invalid input")
|
||||||
|
return fmt.Errorf("invalid input")
|
||||||
|
}
|
||||||
|
|
||||||
|
oldRev, newRev := parts[0], parts[1]
|
||||||
|
|
||||||
|
var changedFiles string
|
||||||
|
if oldRev == BaseHash {
|
||||||
|
// First commit
|
||||||
|
if changedFiles, err = getChangedFiles(newRev); err != nil {
|
||||||
|
_, _ = fmt.Fprintln(er, "Failed to get changed files")
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if changedFiles, err = getChangedFiles(fmt.Sprintf("%s..%s", oldRev, newRev)); err != nil {
|
||||||
|
_, _ = fmt.Fprintln(er, "Failed to get changed files")
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var currentCommit string
|
||||||
|
for _, file := range strings.Fields(changedFiles) {
|
||||||
|
if strings.HasPrefix(file, "/") {
|
||||||
|
currentCommit = file[1:]
|
||||||
|
}
|
||||||
|
|
||||||
|
if strings.Contains(file[1:], "/") {
|
||||||
|
disallowedFiles = append(disallowedFiles, file)
|
||||||
|
disallowedCommits = append(disallowedCommits, currentCommit[0:7])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(disallowedFiles) > 0 {
|
||||||
|
_, _ = fmt.Fprintln(out, "\nPushing files in directories is not allowed:")
|
||||||
|
for i := range disallowedFiles {
|
||||||
|
_, _ = fmt.Fprintf(out, " %s (%s)\n", disallowedFiles[i], disallowedCommits[i])
|
||||||
|
}
|
||||||
|
_, _ = fmt.Fprintln(out)
|
||||||
|
return fmt.Errorf("pushing files in directories is not allowed: %s", disallowedFiles)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func getChangedFiles(rev string) (string, error) {
|
||||||
|
cmd := exec.Command("git", "log", "--name-only", "--format=/%H", "--diff-filter=AM", rev)
|
||||||
|
|
||||||
|
var out bytes.Buffer
|
||||||
|
cmd.Stdout = &out
|
||||||
|
err := cmd.Run()
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
return out.String(), nil
|
||||||
|
}
|
|
@ -134,7 +134,7 @@ func gitHttp(ctx echo.Context) error {
|
||||||
gist.Uuid = strings.Replace(uuidGist.String(), "-", "", -1)
|
gist.Uuid = strings.Replace(uuidGist.String(), "-", "", -1)
|
||||||
gist.Title = "gist:" + gist.Uuid
|
gist.Title = "gist:" + gist.Uuid
|
||||||
|
|
||||||
if err = gist.InitRepositoryViaInit(ctx); err != nil {
|
if err = gist.InitRepository(); err != nil {
|
||||||
return errorRes(500, "Cannot init repository in the file system", err)
|
return errorRes(500, "Cannot init repository in the file system", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -193,6 +193,7 @@ func pack(ctx echo.Context, serviceType string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
repositoryPath := getData(ctx, "repositoryPath").(string)
|
repositoryPath := getData(ctx, "repositoryPath").(string)
|
||||||
|
gist := getData(ctx, "gist").(*db.Gist)
|
||||||
|
|
||||||
var stderr bytes.Buffer
|
var stderr bytes.Buffer
|
||||||
cmd := exec.Command("git", serviceType, "--stateless-rpc", repositoryPath)
|
cmd := exec.Command("git", serviceType, "--stateless-rpc", repositoryPath)
|
||||||
|
@ -200,13 +201,15 @@ func pack(ctx echo.Context, serviceType string) error {
|
||||||
cmd.Stdin = reqBody
|
cmd.Stdin = reqBody
|
||||||
cmd.Stdout = ctx.Response().Writer
|
cmd.Stdout = ctx.Response().Writer
|
||||||
cmd.Stderr = &stderr
|
cmd.Stderr = &stderr
|
||||||
|
cmd.Env = os.Environ()
|
||||||
|
cmd.Env = append(cmd.Env, "OPENGIST_REPOSITORY_URL_INTERNAL="+git.RepositoryUrl(ctx, gist.User.Username, gist.Identifier()))
|
||||||
|
|
||||||
if err = cmd.Run(); err != nil {
|
if err = cmd.Run(); err != nil {
|
||||||
return errorRes(500, "Cannot run git "+serviceType+" ; "+stderr.String(), err)
|
return errorRes(500, "Cannot run git "+serviceType+" ; "+stderr.String(), err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// updatedAt is updated only if serviceType is receive-pack
|
// updatedAt is updated only if serviceType is receive-pack
|
||||||
if serviceType == "receive-pack" {
|
if serviceType == "receive-pack" {
|
||||||
gist := getData(ctx, "gist").(*db.Gist)
|
|
||||||
|
|
||||||
if hasNoCommits, err := git.HasNoCommits(gist.User.Username, gist.Uuid); err != nil {
|
if hasNoCommits, err := git.HasNoCommits(gist.User.Username, gist.Uuid); err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -163,8 +163,8 @@ func usernameProcess(ctx echo.Context) error {
|
||||||
return redirect(ctx, "/settings")
|
return redirect(ctx, "/settings")
|
||||||
}
|
}
|
||||||
|
|
||||||
sourceDir := filepath.Join(config.C.OpengistHome, git.ReposDirectory, strings.ToLower(user.Username))
|
sourceDir := filepath.Join(config.GetHomeDir(), git.ReposDirectory, strings.ToLower(user.Username))
|
||||||
destinationDir := filepath.Join(config.C.OpengistHome, git.ReposDirectory, strings.ToLower(dto.Username))
|
destinationDir := filepath.Join(config.GetHomeDir(), git.ReposDirectory, strings.ToLower(dto.Username))
|
||||||
|
|
||||||
if _, err := os.Stat(sourceDir); !os.IsNotExist(err) {
|
if _, err := os.Stat(sourceDir); !os.IsNotExist(err) {
|
||||||
err := os.Rename(sourceDir, destinationDir)
|
err := os.Rename(sourceDir, destinationDir)
|
||||||
|
|
|
@ -125,6 +125,8 @@ func structToURLValues(s interface{}) url.Values {
|
||||||
}
|
}
|
||||||
|
|
||||||
func setup(t *testing.T) {
|
func setup(t *testing.T) {
|
||||||
|
_ = os.Setenv("OPENGIST_SKIP_GIT_HOOKS", "1")
|
||||||
|
|
||||||
err := config.InitConfig("")
|
err := config.InitConfig("")
|
||||||
require.NoError(t, err, "Could not init config")
|
require.NoError(t, err, "Could not init config")
|
||||||
|
|
||||||
|
@ -159,7 +161,10 @@ func teardown(t *testing.T, s *testServer) {
|
||||||
err := db.Close()
|
err := db.Close()
|
||||||
require.NoError(t, err, "Could not close database")
|
require.NoError(t, err, "Could not close database")
|
||||||
|
|
||||||
err = os.RemoveAll(path.Join(config.C.OpengistHome, "tests"))
|
err = os.RemoveAll(path.Join(config.GetHomeDir(), "tests"))
|
||||||
|
require.NoError(t, err, "Could not remove repos directory")
|
||||||
|
|
||||||
|
err = os.RemoveAll(path.Join(config.GetHomeDir(), "tmp", "repos"))
|
||||||
require.NoError(t, err, "Could not remove repos directory")
|
require.NoError(t, err, "Could not remove repos directory")
|
||||||
|
|
||||||
// err = os.RemoveAll(path.Join(config.C.OpengistHome, "testsindex"))
|
// err = os.RemoveAll(path.Join(config.C.OpengistHome, "testsindex"))
|
||||||
|
|
77
opengist.go
77
opengist.go
|
@ -1,81 +1,12 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"flag"
|
"github.com/thomiceli/opengist/internal/cli"
|
||||||
"fmt"
|
|
||||||
"github.com/rs/zerolog/log"
|
|
||||||
"github.com/thomiceli/opengist/internal/config"
|
|
||||||
"github.com/thomiceli/opengist/internal/db"
|
|
||||||
"github.com/thomiceli/opengist/internal/git"
|
|
||||||
"github.com/thomiceli/opengist/internal/index"
|
|
||||||
"github.com/thomiceli/opengist/internal/memdb"
|
|
||||||
"github.com/thomiceli/opengist/internal/ssh"
|
|
||||||
"github.com/thomiceli/opengist/internal/web"
|
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func initialize() {
|
|
||||||
fmt.Println("Opengist v" + config.OpengistVersion)
|
|
||||||
|
|
||||||
configPath := flag.String("config", "", "Path to a config file in YML format")
|
|
||||||
flag.Parse()
|
|
||||||
|
|
||||||
if err := config.InitConfig(*configPath); err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
if err := os.MkdirAll(filepath.Join(config.GetHomeDir()), 0755); err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
config.InitLog()
|
|
||||||
|
|
||||||
gitVersion, err := git.GetGitVersion()
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal().Err(err).Send()
|
|
||||||
}
|
|
||||||
|
|
||||||
if ok, err := config.CheckGitVersion(gitVersion); err != nil {
|
|
||||||
log.Fatal().Err(err).Send()
|
|
||||||
} else if !ok {
|
|
||||||
log.Warn().Msg("Git version may be too old, as Opengist has not been tested prior git version 2.28 and some features would not work. " +
|
|
||||||
"Current git version: " + gitVersion)
|
|
||||||
}
|
|
||||||
|
|
||||||
homePath := config.GetHomeDir()
|
|
||||||
log.Info().Msg("Data directory: " + homePath)
|
|
||||||
|
|
||||||
if err := os.MkdirAll(filepath.Join(homePath, "repos"), 0755); err != nil {
|
|
||||||
log.Fatal().Err(err).Send()
|
|
||||||
}
|
|
||||||
if err := os.MkdirAll(filepath.Join(homePath, "tmp", "repos"), 0755); err != nil {
|
|
||||||
log.Fatal().Err(err).Send()
|
|
||||||
}
|
|
||||||
if err := os.MkdirAll(filepath.Join(homePath, "custom"), 0755); err != nil {
|
|
||||||
log.Fatal().Err(err).Send()
|
|
||||||
}
|
|
||||||
log.Info().Msg("Database file: " + filepath.Join(homePath, config.C.DBFilename))
|
|
||||||
if err := db.Setup(filepath.Join(homePath, config.C.DBFilename), false); err != nil {
|
|
||||||
log.Fatal().Err(err).Msg("Failed to initialize database")
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := memdb.Setup(); err != nil {
|
|
||||||
log.Fatal().Err(err).Msg("Failed to initialize in memory database")
|
|
||||||
}
|
|
||||||
|
|
||||||
if config.C.IndexEnabled {
|
|
||||||
log.Info().Msg("Index directory: " + filepath.Join(homePath, config.C.IndexDirname))
|
|
||||||
if err := index.Open(filepath.Join(homePath, config.C.IndexDirname)); err != nil {
|
|
||||||
log.Fatal().Err(err).Msg("Failed to open index")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
initialize()
|
if err := cli.App(); err != nil {
|
||||||
|
os.Exit(1)
|
||||||
go web.NewServer(os.Getenv("OG_DEV") == "1").Start()
|
}
|
||||||
go ssh.Start()
|
|
||||||
|
|
||||||
select {}
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue