From cbc339b60d5b25ad2b2685de4303f78d0efa51fe Mon Sep 17 00:00:00 2001 From: Fazlul Shahriar Date: Wed, 25 Dec 2019 17:01:42 -0500 Subject: [PATCH] Add Plan 9 support Not all the tests pass yet but this makes go-git usable on Plan 9. Please merge this after https://github.com/src-d/go-billy/pull/78. Fixes #756 Signed-off-by: Fazlul Shahriar --- go.sum | 2 ++ repository_plan9_test.go | 47 ++++++++++++++++++++++++++++++++++++++++ worktree_plan9.go | 31 ++++++++++++++++++++++++++ 3 files changed, 80 insertions(+) create mode 100644 repository_plan9_test.go create mode 100644 worktree_plan9.go diff --git a/go.sum b/go.sum index 65551c165..21a89fb00 100644 --- a/go.sum +++ b/go.sum @@ -18,6 +18,7 @@ github.com/gliderlabs/ssh v0.2.2 h1:6zsha5zo/TWhRhwqCD3+EarCAgZ2yN28ipRnGPnwkI0= github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= 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= @@ -77,6 +78,7 @@ golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e h1:D5TXcfTk7xF7hvieo4QErS3qq golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190729092621-ff9f1409240a/go.mod h1:jcCCGcm9btYwXyDqrUWc6MKQKKGJCWEQ3AfLSRIbEuI= diff --git a/repository_plan9_test.go b/repository_plan9_test.go new file mode 100644 index 000000000..00ebeed00 --- /dev/null +++ b/repository_plan9_test.go @@ -0,0 +1,47 @@ +package git + +import ( + "fmt" + "strings" +) + +// preReceiveHook returns the bytes of a pre-receive hook script +// that prints m before exiting successfully +func preReceiveHook(m string) []byte { + return []byte(fmt.Sprintf("#!/bin/rc\necho -n %s\n", quote(m))) +} + +const quoteChar = '\'' + +func needsQuote(s string) bool { + for i := 0; i < len(s); i++ { + c := s[i] + if c == quoteChar || c <= ' ' { // quote, blanks, or control characters + return true + } + } + return false +} + +// Quote adds single quotes to s in the style of rc(1) if they are needed. +// The behaviour should be identical to Plan 9's quote(3). +func quote(s string) string { + if s == "" { + return "''" + } + if !needsQuote(s) { + return s + } + var b strings.Builder + b.Grow(10 + len(s)) // Enough room for few quotes + b.WriteByte(quoteChar) + for i := 0; i < len(s); i++ { + c := s[i] + if c == quoteChar { + b.WriteByte(quoteChar) + } + b.WriteByte(c) + } + b.WriteByte(quoteChar) + return b.String() +} diff --git a/worktree_plan9.go b/worktree_plan9.go new file mode 100644 index 000000000..16d3915af --- /dev/null +++ b/worktree_plan9.go @@ -0,0 +1,31 @@ +package git + +import ( + "syscall" + "time" + + "gopkg.in/src-d/go-git.v4/plumbing/format/index" +) + +func init() { + fillSystemInfo = func(e *index.Entry, sys interface{}) { + if os, ok := sys.(*syscall.Dir); ok { + // Plan 9 doesn't have a CreatedAt field. + e.CreatedAt = time.Unix(int64(os.Mtime), 0) + + e.Dev = uint32(os.Dev) + + // Plan 9 has no Inode. + // ext2srv(4) appears to store Inode in Qid.Path. + e.Inode = uint32(os.Qid.Path) + + // Plan 9 has string UID/GID + e.GID = 0 + e.UID = 0 + } + } +} + +func isSymlinkWindowsNonAdmin(err error) bool { + return true +}