Skip to content

Commit bda6253

Browse files
committed
feat: add embedded file utilities
1 parent 6a5e93e commit bda6253

File tree

4 files changed

+75
-20
lines changed

4 files changed

+75
-20
lines changed

README.md

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,6 @@
11
# Flexible File System
22

3-
![GitHub Tag](https://img.shields.io/github/v/tag/go-universal/fs?sort=semver&label=version)
4-
[![Go Reference](https://pkg.go.dev/badge/github.com/go-universal/fs.svg)](https://pkg.go.dev/github.com/go-universal/fs)
5-
[![License](https://img.shields.io/badge/license-ISC-blue.svg)](https://github.com/go-universal/fs/blob/main/LICENSE)
6-
[![Go Report Card](https://goreportcard.com/badge/github.com/go-universal/fs)](https://goreportcard.com/report/github.com/go-universal/fs)
7-
![Contributors](https://img.shields.io/github/contributors/go-universal/fs)
8-
![Issues](https://img.shields.io/github/issues/go-universal/fs)
3+
![GitHub Tag](https://img.shields.io/github/v/tag/go-universal/fs?sort=semver&label=version) [![Go Reference](https://pkg.go.dev/badge/github.com/go-universal/fs.svg)](https://pkg.go.dev/github.com/go-universal/fs) [![License](https://img.shields.io/badge/license-ISC-blue.svg)](https://github.com/go-universal/fs/blob/main/LICENSE) [![Go Report Card](https://goreportcard.com/badge/github.com/go-universal/fs)](https://goreportcard.com/report/github.com/go-universal/fs) ![Contributors](https://img.shields.io/github/contributors/go-universal/fs) ![Issues](https://img.shields.io/github/issues/go-universal/fs)
94

105
The `fs` package provides a flexible file system abstraction for working with both local and embedded file systems. It offers various utilities for file operations such as checking existence, reading files, searching, and more.
116

@@ -40,7 +35,7 @@ Creates a `FlexibleFS` instance backed by the provided embedded file system.
4035
//go:embed *.go
4136
var embeds embed.FS
4237

43-
fs := fs.NewEmbed(embeds)
38+
fs := fs.NewEmbed(embeds, "prefix")
4439
```
4540

4641
## Exists
@@ -125,6 +120,30 @@ if err != nil {
125120
fmt.Println("Found files:", results)
126121
```
127122

123+
## PathOf
124+
125+
Joins the provided path parts into a single normalized path, applying the file system's prefix if applicable.
126+
127+
```go
128+
fullPath := embeddedFs.PathOf("relative", "path", "to", "file")
129+
```
130+
131+
## Prefix
132+
133+
Returns the path prefix for embedded file system.
134+
135+
```go
136+
prefix := fs.Prefix()
137+
```
138+
139+
## IsEmbedded
140+
141+
Returns true if the file system is an embedded file system.
142+
143+
```go
144+
isEmbedded := fs.IsEmbedded()
145+
```
146+
128147
## FS
129148

130149
Returns the underlying `fs.FS` interface of the file system.

fs.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,17 @@ type FlexibleFS interface {
3333
// path. It returns a slice of paths of the found files and an error if any occurs.
3434
Lookup(dir, pattern string) ([]string, error)
3535

36+
// PathOf joins the provided path parts into a single normalized path,
37+
// applying the file system's prefix if applicable. It ensures the resulting
38+
// path is consistent with the file system's internal structure and prefixing rules.
39+
PathOf(parts ...string) string
40+
41+
// Prefix returns the path prefix for embedded file system.
42+
Prefix() string
43+
44+
// IsEmbedded returns true if the file system is an embedded file system.
45+
IsEmbedded() bool
46+
3647
// FS returns the underlying fs.FS interface of the file system.
3748
FS() fs.FS
3849

fs_flexible.go

Lines changed: 37 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,22 +12,32 @@ import (
1212

1313
// flexible is a concrete implementation of the FlexibleFS interface.
1414
type flexible struct {
15-
files fs.FS
15+
files fs.FS
16+
prefix string
17+
isEmbedded bool
1618
}
1719

1820
// NewDir creates a FlexibleFS instance backed by the local file system
1921
// at the specified directory path.
2022
func NewDir(path string) FlexibleFS {
21-
return &flexible{files: os.DirFS(path)}
23+
return &flexible{
24+
files: os.DirFS(path),
25+
prefix: "",
26+
isEmbedded: false,
27+
}
2228
}
2329

2430
// NewEmbed creates a FlexibleFS instance backed by the provided embedded
2531
// file system.
26-
func NewEmbed(embeddedFS embed.FS) FlexibleFS {
27-
return &flexible{files: embeddedFS}
32+
func NewEmbed(embeddedFS embed.FS, prefix string) FlexibleFS {
33+
return &flexible{
34+
files: embeddedFS,
35+
prefix: prefix,
36+
isEmbedded: true,
37+
}
2838
}
2939

30-
func (f flexible) Exists(path string) (bool, error) {
40+
func (f *flexible) Exists(path string) (bool, error) {
3141
path = normalizePath(path)
3242
info, err := fs.Stat(f.files, path)
3343

@@ -42,17 +52,17 @@ func (f flexible) Exists(path string) (bool, error) {
4252
return !info.IsDir(), nil
4353
}
4454

45-
func (f flexible) Open(path string) (fs.File, error) {
55+
func (f *flexible) Open(path string) (fs.File, error) {
4656
path = normalizePath(path)
4757
return f.files.Open(path)
4858
}
4959

50-
func (f flexible) ReadFile(path string) ([]byte, error) {
60+
func (f *flexible) ReadFile(path string) ([]byte, error) {
5161
path = normalizePath(path)
5262
return fs.ReadFile(f.files, path)
5363
}
5464

55-
func (f flexible) Find(dir, pattern string) (*string, error) {
65+
func (f *flexible) Find(dir, pattern string) (*string, error) {
5666
var result string
5767
dir = normalizePath(dir)
5868

@@ -87,7 +97,7 @@ func (f flexible) Find(dir, pattern string) (*string, error) {
8797
return &result, nil
8898
}
8999

90-
func (f flexible) Search(dir, phrase, ignore, ext string) (*string, error) {
100+
func (f *flexible) Search(dir, phrase, ignore, ext string) (*string, error) {
91101
var result string
92102
var err error
93103
dir = normalizePath(dir)
@@ -143,7 +153,7 @@ func (f flexible) Search(dir, phrase, ignore, ext string) (*string, error) {
143153
return &result, nil
144154
}
145155

146-
func (f flexible) Lookup(dir, pattern string) ([]string, error) {
156+
func (f *flexible) Lookup(dir, pattern string) ([]string, error) {
147157
var result []string
148158
dir = normalizePath(dir)
149159

@@ -177,10 +187,25 @@ func (f flexible) Lookup(dir, pattern string) ([]string, error) {
177187
return result, nil
178188
}
179189

180-
func (f flexible) FS() fs.FS {
190+
func (f *flexible) PathOf(parts ...string) string {
191+
if f.prefix == "" {
192+
return normalizePath(append([]string{"."}, parts...)...)
193+
}
194+
return normalizePath(append([]string{".", f.prefix}, parts...)...)
195+
}
196+
197+
func (f *flexible) Prefix() string {
198+
return f.prefix
199+
}
200+
201+
func (f *flexible) IsEmbedded() bool {
202+
return f.isEmbedded
203+
}
204+
205+
func (f *flexible) FS() fs.FS {
181206
return f.files
182207
}
183208

184-
func (f flexible) Http() http.FileSystem {
209+
func (f *flexible) Http() http.FileSystem {
185210
return http.FS(f.files)
186211
}

fs_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ func TestDir(t *testing.T) {
8585
}
8686

8787
func TestEmbed(t *testing.T) {
88-
fs := fs.NewEmbed(embeds)
88+
fs := fs.NewEmbed(embeds, "")
8989
invalid := "missing.go"
9090
valid := "fs.go"
9191

0 commit comments

Comments
 (0)