main
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}