diff --git a/misc/git/repos.go b/misc/git/repos.go index 73888c56..93568e30 100644 --- a/misc/git/repos.go +++ b/misc/git/repos.go @@ -547,7 +547,7 @@ func init() { if u, ok := list[kit.ParseURL(remote).Host]; ok { password, _ = u.User.Password() } - m.Sort("repos,status,file").Status(mdb.TIME, last, kit.Select(aaa.TECH, aaa.VOID, password == ""), m.Option(aaa.EMAIL), REMOTE, remote, kit.MDB_COUNT, kit.Split(m.FormatSize())[0], kit.MDB_COST, m.FormatCost()) + m.Sort("repos,status,file").Status(mdb.TIME, last, REMOTE, remote, kit.Select(aaa.TECH, aaa.VOID, password == ""), m.Option(aaa.EMAIL), kit.MDB_COUNT, kit.Split(m.FormatSize())[0], kit.MDB_COST, m.FormatCost()) } }}, REMOTE: {Hand: func(m *ice.Message, arg ...string) { diff --git a/misc/git/service.go b/misc/git/service.go index 948c219c..63e413e0 100644 --- a/misc/git/service.go +++ b/misc/git/service.go @@ -3,6 +3,7 @@ package git import ( "compress/flate" "compress/gzip" + "context" "encoding/base64" "fmt" "io" @@ -12,7 +13,12 @@ import ( "strings" "shylinux.com/x/go-git/v5/plumbing" + "shylinux.com/x/go-git/v5/plumbing/protocol/packp" + "shylinux.com/x/go-git/v5/plumbing/transport" "shylinux.com/x/go-git/v5/plumbing/transport/file" + "shylinux.com/x/go-git/v5/plumbing/transport/server" + "shylinux.com/x/go-git/v5/utils/ioutil" + ice "shylinux.com/x/icebergs" "shylinux.com/x/icebergs/base/aaa" "shylinux.com/x/icebergs/base/cli" @@ -48,7 +54,36 @@ func _service_param(m *ice.Message, arg ...string) (string, string) { repos, service := arg[0], kit.Select(arg[len(arg)-1], m.Option(SERVICE)) return _service_path(m, repos), strings.TrimPrefix(service, "git-") } +func _service_repos2(m *ice.Message, arg ...string) error { + repos, service := _service_param(m, arg...) + m.Logs(m.R.Method, service, repos) + info := false + if m.Option(cli.CMD_DIR, repos); strings.HasSuffix(path.Join(arg...), INFO_REFS) { + web.RenderType(m.W, "", kit.Format("application/x-git-%s-advertisement", service)) + _service_writer(m, "# service=git-"+service+lex.NL) + info = true + } else { + web.RenderType(m.W, "", kit.Format("application/x-git-%s-result", service)) + } + + reader, err := _service_reader(m) + if err != nil { + return err + } + defer reader.Close() + out := nfs.NewWriteCloser(func(buf []byte) (int, error) { return m.W.Write(buf) }, func() error { return nil }) + stream := ServerCommand{Stdin: reader, Stdout: out, Stderr: out} + + if service == RECEIVE_PACK { + defer m.Cmd(Prefix(SERVICE), mdb.CREATE, mdb.NAME, path.Base(repos)) + return ServeReceivePack(info, stream, repos) + } else { + return ServeUploadPack(info, stream, repos) + } +} func _service_repos(m *ice.Message, arg ...string) error { + return _service_repos2(m, arg...) + repos, service := _service_param(m, arg...) m.Logs(m.R.Method, service, repos) if m.Option(cli.CMD_DIR, repos); strings.HasSuffix(path.Join(arg...), INFO_REFS) { @@ -181,3 +216,81 @@ func init() { }}, }) } + +func ServeReceivePack(info bool, srvCmd ServerCommand, path string) error { + ep, err := transport.NewEndpoint(path) + if err != nil { + return err + } + s, err := server.DefaultServer.NewReceivePackSession(ep, nil) + if err != nil { + return fmt.Errorf("error creating session: %s", err) + } + return serveReceivePack(info, srvCmd, s) +} +func ServeUploadPack(info bool, srvCmd ServerCommand, path string) error { + ep, err := transport.NewEndpoint(path) + if err != nil { + return err + } + s, err := server.DefaultServer.NewUploadPackSession(ep, nil) + if err != nil { + return fmt.Errorf("error creating session: %s", err) + } + return serveUploadPack(info, srvCmd, s) +} + +type ServerCommand struct { + Stderr io.Writer + Stdout io.WriteCloser + Stdin io.Reader +} + +func serveReceivePack(info bool, cmd ServerCommand, s transport.ReceivePackSession) error { + if info { + ar, err := s.AdvertisedReferences() + if err != nil { + return fmt.Errorf("internal error in advertised references: %s", err) + } + if err := ar.Encode(cmd.Stdout); err != nil { + return fmt.Errorf("error in advertised references encoding: %s", err) + } + return nil + } + req := packp.NewReferenceUpdateRequest() + if err := req.Decode(cmd.Stdin); err != nil { + return fmt.Errorf("error decoding: %s", err) + } + rs, err := s.ReceivePack(context.TODO(), req) + if rs != nil { + if err := rs.Encode(cmd.Stdout); err != nil { + return fmt.Errorf("error in encoding report status %s", err) + } + } + if err != nil { + return fmt.Errorf("error in receive pack: %s", err) + } + return nil +} +func serveUploadPack(info bool, cmd ServerCommand, s transport.UploadPackSession) (err error) { + ioutil.CheckClose(cmd.Stdout, &err) + if info { + ar, err := s.AdvertisedReferences() + if err != nil { + return err + } + if err := ar.Encode(cmd.Stdout); err != nil { + return err + } + return nil + } + req := packp.NewUploadPackRequest() + if err := req.Decode(cmd.Stdin); err != nil { + return err + } + resp, err := s.UploadPack(context.TODO(), req) + if err != nil { + return err + } + return resp.Encode(cmd.Stdout) +} diff --git a/misc/git/status.go b/misc/git/status.go index 955fc948..6e5006a0 100644 --- a/misc/git/status.go +++ b/misc/git/status.go @@ -111,9 +111,7 @@ func init() { case nfs.TO: m.Cmd(web.BROAD, func(value ice.Maps) { m.Push(arg[0], kit.Format("http://%s:%s/", value[tcp.HOST], value[tcp.PORT])) }) case REMOTE: - m.Cmd(web.BROAD, func(value ice.Maps) { m.Push(arg[0], kit.Format("http://%s:%s/x/", value[tcp.HOST], value[tcp.PORT])) }) - m.Push(arg[0], "http://localhost:9020/x/") - m.Push(arg[0], "https://shylinux.com/x/") + m.Cmd("web.spide", func(value ice.Maps) { m.Push(arg[0], kit.ParseURLMap(value["client.url"])["origin"]+"/x/") }) } return } @@ -174,7 +172,7 @@ func init() { m.Action(CONFIGS).Echo("please config email and name. ").EchoButton(CONFIGS) } else if len(arg) == 0 { kit.If(config != nil, func() { m.Option(aaa.EMAIL, kit.Select(mdb.Config(m, aaa.EMAIL), config.User.Email)) }) - m.Cmdy(REPOS, STATUS).Action(PULL, PUSH, "oauth", CONFIGS, INSTEADOF, cli.RESTART) + m.Cmdy(REPOS, STATUS).Action(PULL, PUSH, INSTEADOF, "oauth", CONFIGS, cli.RESTART) } else { m.Cmdy(REPOS, arg[0], MASTER, INDEX, m.Cmdv(REPOS, arg[0], MASTER, INDEX, nfs.FILE)) }