Skip to content

Commit 24d71a1

Browse files
committed
fix: bring os_js.go up to date with os.go
Recent changes to os_js.go added WithBoundOS and ChrootOSFS. These changes were not propagated to os_js.go, which results in the following build failures in go-git: % GOOS=js GOARCH=wasm gb ./... github.com/go-git/go-git/v6 ./remote.go:214:32: undefined: osfs.WithBoundOS ./repository.go:348:29: undefined: osfs.WithBoundOS ./repository.go:353:28: undefined: osfs.WithBoundOS ./repository.go:460:28: undefined: osfs.WithBoundOS ./repository.go:468:44: undefined: osfs.WithBoundOS ./repository.go:528:32: undefined: osfs.WithBoundOS ./repository.go:531:46: undefined: osfs.WithBoundOS ./repository.go:551:36: undefined: osfs.WithBoundOS ./repository.go:553:62: undefined: osfs.WithBoundOS This commit brings os_js.go up to date with os.go to fix this. All tests pass with GOOS=js GOARCH=wasm now. Signed-off-by: Christian Stewart <christian@aperture.us>
1 parent 14bb35b commit 24d71a1

2 files changed

Lines changed: 110 additions & 2 deletions

File tree

osfs/os_js.go

Lines changed: 102 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
package osfs
44

55
import (
6+
"path/filepath"
7+
"strings"
8+
69
"github.com/go-git/go-billy/v6"
710
"github.com/go-git/go-billy/v6/helper/chroot"
811
"github.com/go-git/go-billy/v6/memfs"
@@ -16,8 +19,105 @@ var globalMemFs = memfs.New()
1619
var Default = memfs.New()
1720

1821
// New returns a new OS filesystem.
19-
func New(baseDir string, _ ...Option) billy.Filesystem {
22+
// By default paths are deduplicated, but still enforced
23+
// under baseDir. For more info refer to WithDeduplicatePath.
24+
func New(baseDir string, opts ...Option) billy.Filesystem {
25+
o := &options{
26+
deduplicatePath: true,
27+
}
28+
for _, opt := range opts {
29+
opt(o)
30+
}
31+
32+
if o.Type == BoundOSFS {
33+
return newBoundOS(baseDir, o.deduplicatePath)
34+
}
35+
36+
return newChrootOS(baseDir)
37+
}
38+
39+
func newChrootOS(baseDir string) billy.Filesystem {
2040
return chroot.New(Default, Default.Join("/", baseDir))
2141
}
2242

23-
type options struct{}
43+
// BoundOS is a fs implementation based on the js/wasm in-memory filesystem
44+
// which is bound to a base dir.
45+
type BoundOS struct {
46+
billy.Filesystem
47+
baseDir string
48+
deduplicatePath bool
49+
}
50+
51+
func newBoundOS(d string, deduplicatePath bool) billy.Filesystem {
52+
baseDir := globalMemFs.Join("/", d)
53+
return &BoundOS{
54+
Filesystem: chroot.New(globalMemFs, baseDir),
55+
baseDir: baseDir,
56+
deduplicatePath: deduplicatePath,
57+
}
58+
}
59+
60+
// Chroot returns a new BoundOS filesystem, with the base dir set to the
61+
// result of joining the provided path with the underlying base dir.
62+
func (fs *BoundOS) Chroot(path string) (billy.Filesystem, error) {
63+
joined, err := fs.abs(path)
64+
if err != nil {
65+
return nil, err
66+
}
67+
return New(joined, WithBoundOS(), WithDeduplicatePath(fs.deduplicatePath)), nil
68+
}
69+
70+
// Root returns the current base dir of the billy.Filesystem.
71+
func (fs *BoundOS) Root() string {
72+
return fs.baseDir
73+
}
74+
75+
func (fs *BoundOS) abs(filename string) (string, error) {
76+
if filename == "." || filename == "" {
77+
return fs.baseDir, nil
78+
}
79+
80+
filename = filepath.ToSlash(filename)
81+
filename = filepath.Clean(filename)
82+
if strings.HasPrefix(filename, "..") {
83+
return "", billy.ErrCrossedBoundary
84+
}
85+
86+
filename = strings.TrimPrefix(filename, string(filepath.Separator))
87+
return filepath.Clean(filepath.Join(fs.baseDir, filepath.FromSlash(filename))), nil
88+
}
89+
90+
// WithBoundOS returns the option of using a Bound filesystem OS.
91+
func WithBoundOS() Option {
92+
return func(o *options) {
93+
o.Type = BoundOSFS
94+
}
95+
}
96+
97+
// WithChrootOS returns the option of using a Chroot filesystem OS.
98+
func WithChrootOS() Option {
99+
return func(o *options) {
100+
o.Type = ChrootOSFS
101+
}
102+
}
103+
104+
// WithDeduplicatePath toggles the deduplication of the base dir in the path.
105+
// This option is accepted for API parity with non-js builds and has no effect
106+
// on the js/wasm in-memory implementation.
107+
func WithDeduplicatePath(enabled bool) Option {
108+
return func(o *options) {
109+
o.deduplicatePath = enabled
110+
}
111+
}
112+
113+
type options struct {
114+
Type
115+
deduplicatePath bool
116+
}
117+
118+
type Type int
119+
120+
const (
121+
ChrootOSFS Type = iota
122+
BoundOSFS
123+
)

osfs/os_js_test.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,5 +41,13 @@ func TestDefault(t *testing.T) {
4141
}
4242
}
4343

44+
func TestWithBoundOSReturnsBoundOS(t *testing.T) {
45+
got := New(t.TempDir(), WithBoundOS())
46+
assert.IsType(t, &BoundOS{}, got)
47+
}
48+
4449
// API call assertions
4550
var _ = New("/")
51+
var _ = New("/", WithBoundOS())
52+
var _ = New("/", WithChrootOS())
53+
var _ = New("/", WithDeduplicatePath(false))

0 commit comments

Comments
 (0)