main
Raw Download raw file
  1//go:build !js
  2// +build !js
  3
  4package osfs
  5
  6import (
  7	"os"
  8	"path/filepath"
  9
 10	"github.com/go-git/go-billy/v5"
 11	"github.com/go-git/go-billy/v5/helper/chroot"
 12)
 13
 14// ChrootOS is a legacy filesystem based on a "soft chroot" of the os filesystem.
 15// Although this is still the default os filesystem, consider using BoundOS instead.
 16//
 17// Behaviours of note:
 18//  1. A "soft chroot" translates the base dir to "/" for the purposes of the
 19//     fs abstraction.
 20//  2. Symlinks targets may be modified to be kept within the chroot bounds.
 21//  3. Some file modes does not pass-through the fs abstraction.
 22//  4. The combination of 1 and 2 may cause go-git to think that a Git repository
 23//     is dirty, when in fact it isn't.
 24type ChrootOS struct{}
 25
 26func newChrootOS(baseDir string) billy.Filesystem {
 27	return chroot.New(&ChrootOS{}, baseDir)
 28}
 29
 30func (fs *ChrootOS) Create(filename string) (billy.File, error) {
 31	return fs.OpenFile(filename, os.O_RDWR|os.O_CREATE|os.O_TRUNC, defaultCreateMode)
 32}
 33
 34func (fs *ChrootOS) OpenFile(filename string, flag int, perm os.FileMode) (billy.File, error) {
 35	return openFile(filename, flag, perm, fs.createDir)
 36}
 37
 38func (fs *ChrootOS) createDir(fullpath string) error {
 39	dir := filepath.Dir(fullpath)
 40	if dir != "." {
 41		if err := os.MkdirAll(dir, defaultDirectoryMode); err != nil {
 42			return err
 43		}
 44	}
 45
 46	return nil
 47}
 48
 49func (fs *ChrootOS) ReadDir(dir string) ([]os.FileInfo, error) {
 50	return readDir(dir)
 51}
 52
 53func (fs *ChrootOS) Rename(from, to string) error {
 54	if err := fs.createDir(to); err != nil {
 55		return err
 56	}
 57
 58	return rename(from, to)
 59}
 60
 61func (fs *ChrootOS) MkdirAll(path string, perm os.FileMode) error {
 62	return os.MkdirAll(path, defaultDirectoryMode)
 63}
 64
 65func (fs *ChrootOS) Open(filename string) (billy.File, error) {
 66	return fs.OpenFile(filename, os.O_RDONLY, 0)
 67}
 68
 69func (fs *ChrootOS) Stat(filename string) (os.FileInfo, error) {
 70	return os.Stat(filename)
 71}
 72
 73func (fs *ChrootOS) Remove(filename string) error {
 74	return os.Remove(filename)
 75}
 76
 77func (fs *ChrootOS) TempFile(dir, prefix string) (billy.File, error) {
 78	if err := fs.createDir(dir + string(os.PathSeparator)); err != nil {
 79		return nil, err
 80	}
 81
 82	return tempFile(dir, prefix)
 83}
 84
 85func (fs *ChrootOS) Join(elem ...string) string {
 86	return filepath.Join(elem...)
 87}
 88
 89func (fs *ChrootOS) RemoveAll(path string) error {
 90	return os.RemoveAll(filepath.Clean(path))
 91}
 92
 93func (fs *ChrootOS) Lstat(filename string) (os.FileInfo, error) {
 94	return os.Lstat(filepath.Clean(filename))
 95}
 96
 97func (fs *ChrootOS) Symlink(target, link string) error {
 98	if err := fs.createDir(link); err != nil {
 99		return err
100	}
101
102	return os.Symlink(target, link)
103}
104
105func (fs *ChrootOS) Readlink(link string) (string, error) {
106	return os.Readlink(link)
107}
108
109// Capabilities implements the Capable interface.
110func (fs *ChrootOS) Capabilities() billy.Capability {
111	return billy.DefaultCapabilities
112}