1
0
Fork 0
forked from forgejo/forgejo

Migrate to go-git/go-git v5.0.0 (#10735)

This commit is contained in:
Lauris BH 2020-03-17 18:19:58 +02:00 committed by GitHub
parent 2f928316db
commit 43c09134a9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
315 changed files with 15239 additions and 92420 deletions

View file

@ -0,0 +1,242 @@
package chroot
import (
"os"
"path/filepath"
"strings"
"github.com/go-git/go-billy/v5"
"github.com/go-git/go-billy/v5/helper/polyfill"
)
// ChrootHelper is a helper to implement billy.Chroot.
type ChrootHelper struct {
underlying billy.Filesystem
base string
}
// New creates a new filesystem wrapping up the given 'fs'.
// The created filesystem has its base in the given ChrootHelperectory of the
// underlying filesystem.
func New(fs billy.Basic, base string) billy.Filesystem {
return &ChrootHelper{
underlying: polyfill.New(fs),
base: base,
}
}
func (fs *ChrootHelper) underlyingPath(filename string) (string, error) {
if isCrossBoundaries(filename) {
return "", billy.ErrCrossedBoundary
}
return fs.Join(fs.Root(), filename), nil
}
func isCrossBoundaries(path string) bool {
path = filepath.ToSlash(path)
path = filepath.Clean(path)
return strings.HasPrefix(path, ".."+string(filepath.Separator))
}
func (fs *ChrootHelper) Create(filename string) (billy.File, error) {
fullpath, err := fs.underlyingPath(filename)
if err != nil {
return nil, err
}
f, err := fs.underlying.Create(fullpath)
if err != nil {
return nil, err
}
return newFile(fs, f, filename), nil
}
func (fs *ChrootHelper) Open(filename string) (billy.File, error) {
fullpath, err := fs.underlyingPath(filename)
if err != nil {
return nil, err
}
f, err := fs.underlying.Open(fullpath)
if err != nil {
return nil, err
}
return newFile(fs, f, filename), nil
}
func (fs *ChrootHelper) OpenFile(filename string, flag int, mode os.FileMode) (billy.File, error) {
fullpath, err := fs.underlyingPath(filename)
if err != nil {
return nil, err
}
f, err := fs.underlying.OpenFile(fullpath, flag, mode)
if err != nil {
return nil, err
}
return newFile(fs, f, filename), nil
}
func (fs *ChrootHelper) Stat(filename string) (os.FileInfo, error) {
fullpath, err := fs.underlyingPath(filename)
if err != nil {
return nil, err
}
return fs.underlying.Stat(fullpath)
}
func (fs *ChrootHelper) Rename(from, to string) error {
var err error
from, err = fs.underlyingPath(from)
if err != nil {
return err
}
to, err = fs.underlyingPath(to)
if err != nil {
return err
}
return fs.underlying.Rename(from, to)
}
func (fs *ChrootHelper) Remove(path string) error {
fullpath, err := fs.underlyingPath(path)
if err != nil {
return err
}
return fs.underlying.Remove(fullpath)
}
func (fs *ChrootHelper) Join(elem ...string) string {
return fs.underlying.Join(elem...)
}
func (fs *ChrootHelper) TempFile(dir, prefix string) (billy.File, error) {
fullpath, err := fs.underlyingPath(dir)
if err != nil {
return nil, err
}
f, err := fs.underlying.(billy.TempFile).TempFile(fullpath, prefix)
if err != nil {
return nil, err
}
return newFile(fs, f, fs.Join(dir, filepath.Base(f.Name()))), nil
}
func (fs *ChrootHelper) ReadDir(path string) ([]os.FileInfo, error) {
fullpath, err := fs.underlyingPath(path)
if err != nil {
return nil, err
}
return fs.underlying.(billy.Dir).ReadDir(fullpath)
}
func (fs *ChrootHelper) MkdirAll(filename string, perm os.FileMode) error {
fullpath, err := fs.underlyingPath(filename)
if err != nil {
return err
}
return fs.underlying.(billy.Dir).MkdirAll(fullpath, perm)
}
func (fs *ChrootHelper) Lstat(filename string) (os.FileInfo, error) {
fullpath, err := fs.underlyingPath(filename)
if err != nil {
return nil, err
}
return fs.underlying.(billy.Symlink).Lstat(fullpath)
}
func (fs *ChrootHelper) Symlink(target, link string) error {
target = filepath.FromSlash(target)
// only rewrite target if it's already absolute
if filepath.IsAbs(target) || strings.HasPrefix(target, string(filepath.Separator)) {
target = fs.Join(fs.Root(), target)
target = filepath.Clean(filepath.FromSlash(target))
}
link, err := fs.underlyingPath(link)
if err != nil {
return err
}
return fs.underlying.(billy.Symlink).Symlink(target, link)
}
func (fs *ChrootHelper) Readlink(link string) (string, error) {
fullpath, err := fs.underlyingPath(link)
if err != nil {
return "", err
}
target, err := fs.underlying.(billy.Symlink).Readlink(fullpath)
if err != nil {
return "", err
}
if !filepath.IsAbs(target) && !strings.HasPrefix(target, string(filepath.Separator)) {
return target, nil
}
target, err = filepath.Rel(fs.base, target)
if err != nil {
return "", err
}
return string(os.PathSeparator) + target, nil
}
func (fs *ChrootHelper) Chroot(path string) (billy.Filesystem, error) {
fullpath, err := fs.underlyingPath(path)
if err != nil {
return nil, err
}
return New(fs.underlying, fullpath), nil
}
func (fs *ChrootHelper) Root() string {
return fs.base
}
func (fs *ChrootHelper) Underlying() billy.Basic {
return fs.underlying
}
// Capabilities implements the Capable interface.
func (fs *ChrootHelper) Capabilities() billy.Capability {
return billy.Capabilities(fs.underlying)
}
type file struct {
billy.File
name string
}
func newFile(fs billy.Filesystem, f billy.File, filename string) billy.File {
filename = fs.Join(fs.Root(), filename)
filename, _ = filepath.Rel(fs.Root(), filename)
return &file{
File: f,
name: filename,
}
}
func (f *file) Name() string {
return f.name
}

View file

@ -0,0 +1,105 @@
package polyfill
import (
"os"
"path/filepath"
"github.com/go-git/go-billy/v5"
)
// Polyfill is a helper that implements all missing method from billy.Filesystem.
type Polyfill struct {
billy.Basic
c capabilities
}
type capabilities struct{ tempfile, dir, symlink, chroot bool }
// New creates a new filesystem wrapping up 'fs' the intercepts all the calls
// made and errors if fs doesn't implement any of the billy interfaces.
func New(fs billy.Basic) billy.Filesystem {
if original, ok := fs.(billy.Filesystem); ok {
return original
}
h := &Polyfill{Basic: fs}
_, h.c.tempfile = h.Basic.(billy.TempFile)
_, h.c.dir = h.Basic.(billy.Dir)
_, h.c.symlink = h.Basic.(billy.Symlink)
_, h.c.chroot = h.Basic.(billy.Chroot)
return h
}
func (h *Polyfill) TempFile(dir, prefix string) (billy.File, error) {
if !h.c.tempfile {
return nil, billy.ErrNotSupported
}
return h.Basic.(billy.TempFile).TempFile(dir, prefix)
}
func (h *Polyfill) ReadDir(path string) ([]os.FileInfo, error) {
if !h.c.dir {
return nil, billy.ErrNotSupported
}
return h.Basic.(billy.Dir).ReadDir(path)
}
func (h *Polyfill) MkdirAll(filename string, perm os.FileMode) error {
if !h.c.dir {
return billy.ErrNotSupported
}
return h.Basic.(billy.Dir).MkdirAll(filename, perm)
}
func (h *Polyfill) Symlink(target, link string) error {
if !h.c.symlink {
return billy.ErrNotSupported
}
return h.Basic.(billy.Symlink).Symlink(target, link)
}
func (h *Polyfill) Readlink(link string) (string, error) {
if !h.c.symlink {
return "", billy.ErrNotSupported
}
return h.Basic.(billy.Symlink).Readlink(link)
}
func (h *Polyfill) Lstat(path string) (os.FileInfo, error) {
if !h.c.symlink {
return nil, billy.ErrNotSupported
}
return h.Basic.(billy.Symlink).Lstat(path)
}
func (h *Polyfill) Chroot(path string) (billy.Filesystem, error) {
if !h.c.chroot {
return nil, billy.ErrNotSupported
}
return h.Basic.(billy.Chroot).Chroot(path)
}
func (h *Polyfill) Root() string {
if !h.c.chroot {
return string(filepath.Separator)
}
return h.Basic.(billy.Chroot).Root()
}
func (h *Polyfill) Underlying() billy.Basic {
return h.Basic
}
// Capabilities implements the Capable interface.
func (h *Polyfill) Capabilities() billy.Capability {
return billy.Capabilities(h.Basic)
}