Skip to content

Commit

Permalink
readme + doc
Browse files Browse the repository at this point in the history
  • Loading branch information
mandelsoft committed Sep 15, 2020
1 parent 2adb287 commit 4781252
Show file tree
Hide file tree
Showing 14 changed files with 350 additions and 19 deletions.
79 changes: 79 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
## VFS - A Virtual Filesystem for GO

A virtual filesystem enables programs to transparently work on any kind
of filesystem-like data source besides the real operating system filesystem
using a uniform single API.

This project provides an API that can be used instead of the native
OS filesytem API. Below this API there might be several technical
implementations that simulate a uniform filesystem for all its users.

- package `osfs` provides access to the real operating system filesystem
observing the current working directory (see [godoc](https://pkg.go.dev/github.com/mandelsoft/vfs/pkg/osfs)).
- package `memoryfs` provides a pure memory based file system supporting
files, directories and symbolic links (see [godoc](https://pkg.go.dev/github.com/mandelsoft/vfs/pkg/memoryfs)).
- package `composefs` provides a virtual filesystem composable of
multiple other virtual filesystems, that can be mounted on top of
a root file system (see [godoc](https://pkg.go.dev/github.com/mandelsoft/vfs/pkg/composefs)).
- package `layerfs` provides a filesystem layer on top of a base filesystem.
The layer can be implemented by any other virtual filesystem, for example
a memory filesystem (see [godoc](https://pkg.go.dev/github.com/mandelsoft/vfs/pkg/layerfs)).
- package `yamlfs` provides a filesystem based on the structure and content of a
yaml document (see [godoc](https://pkg.go.dev/github.com/mandelsoft/vfs/pkg/yamlfs)).
The document can even be changed by filesystem operations.

Besides those new implementations for a virtual filesystem there are
some implementation modifying the bahaviour of a base filesystem:

- package `readonlyfs` provides a read-only view of a base filesystem (see [godoc](https://pkg.go.dev/github.com/mandelsoft/vfs/pkg/readonlyfs)).
- package `cwdfs` provides the notion of a current working directory for
any base filesystem (see [godoc](https://pkg.go.dev/github.com/mandelsoft/vfs/pkg/cwdfs)).
- package `projectionfs` provides a filesystem based on a dedicated directory
of a base filesystem (see [godoc](https://pkg.go.dev/github.com/mandelsoft/vfs/pkg/projectionfs)).

All the implementation packages provide some `New` function to create an
instance of the dedicated filesystem type.

To work with the OS filesystem just create an instance of
the `osfs`:

```golang
import "github.com/mandelsoft/vfs/pkg/osfs"

...

fs := osfs.New()
```

Now the standard go filesystem related `os` API can be used just by replacing
the package `os` by the instance of the virtual filesystem.

```golang

f, err := fs.Open()
if err!=nil {
return nil, err
}
defer f.Close()
vfs.ReadFile()
return ioutil.ReadAll(f)
```

To support this the package `vfs` provides a common interface `FileSystem` that
offers methods similar to the `os` file operations. Additionally an own
`File` interface is provided that replaces the struct `os.File` for the use
in the context of the virtual filesystem. (see [godoc](https://pkg.go.dev/github.com/mandelsoft/vfs/pkg/vfs))

A `FileSystem` may offer a temp directory and a current working directory.
The typical implementations for new kinds of a filesystem do not provide
these features, they rely on the orchestration with dedicated implementations,
for example a `cwdfs.WorkingDirectoryFileSystem` or a
`composedfs.ComposedFileSystem`, which allows mounting a temporary filesystem.
The package `osfs` supports creating a temporary os filesystem based
virtual filesystem residing in a temporary operating system directory.

Additional the interface `VFS` includes the standard filesystem operations
and some implementation independent utility functions based on a virtual
filesystem known from the `os`, `ìoutil` and `filepath` packages.
The function `vfs.New(fs)` can be used to create such a wrapper for
any virtual filesystem.
36 changes: 23 additions & 13 deletions cmd/play/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,22 +20,32 @@ package main

import (
"fmt"
"os"
"reflect"

"gopkg.in/yaml.v2"
)

func main() {
fi, err := os.Open("/lib/cpp2")
if err != nil {
fmt.Printf("open: %s(%s)\n", reflect.TypeOf(err), err)
os.Exit(1)
}
names, err := fi.Readdirnames(0)
func Error(err error) {
if err != nil {
fmt.Printf("dir: %s(%s)\n", reflect.TypeOf(err), err)
os.Exit(1)
}
for _, n := range names {
fmt.Printf("%s\n", n)
panic(err)
}
}

func main() {
in := `
data: !!binary |
VGhpcyBpcyBhIGRlY29kZWQgdGVzdAo=
`

s := map[interface{}]interface{}{}
err := yaml.Unmarshal([]byte(in), s)
Error(err)

fmt.Printf("%d\n", len(s))
fmt.Printf("DATA: %s: %s\n", reflect.TypeOf(s["data"]), s["data"])

s["data"] = string([]byte{255, 255})
b, err := yaml.Marshal(s)
Error(err)
fmt.Printf("RESULT:\n%s\n", b)
}
15 changes: 14 additions & 1 deletion pkg/composefs/compose.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,20 @@ func (c *ComposedFileSystem) MountTempDir(path string) (string, error) {
return "", err
}
c.tempdir = path
return "", err
return path, err
}

func (c *ComposedFileSystem) MountTempFileSysten(path string, fs vfs.FileSystem) (string, error) {
if !vfs.IsAbs(nil, path) {
path = vfs.PathSeparatorString + path
}
path = vfs.Trim(nil, path)
err := c.Mount(path, fs)
if err != nil {
return "", err
}
c.tempdir = path
return path, err
}

func (c *ComposedFileSystem) Mount(path string, fs vfs.FileSystem) error {
Expand Down
21 changes: 21 additions & 0 deletions pkg/composefs/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*
* Copyright 2020 Mandelsoft. All rights reserved.
* This file is licensed under the Apache Software License, v. 2 except as noted
* otherwise in the LICENSE file
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

// Package composefs provides a virtual filesystem implementation for
// orchestrating multiple other virtual filesystems to a single one.
package composefs
21 changes: 21 additions & 0 deletions pkg/cwdfs/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*
* Copyright 2020 Mandelsoft. All rights reserved.
* This file is licensed under the Apache Software License, v. 2 except as noted
* otherwise in the LICENSE file
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

// Package cwdfs provides a virtual filesystem supporting the notion of a
// current working directory based on any kind of base filesystem.
package cwdfs
22 changes: 22 additions & 0 deletions pkg/layerfs/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
* Copyright 2020 Mandelsoft. All rights reserved.
* This file is licensed under the Apache Software License, v. 2 except as noted
* otherwise in the LICENSE file
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

// Package layerfs provides a virtual filesystem supporting a filesytem layer
// on top of a base filesystem, that is used to keep track of all changes
// done to the filesystem. Thereby the root filesystem is not changed.
package layerfs
21 changes: 21 additions & 0 deletions pkg/memoryfs/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*
* Copyright 2020 Mandelsoft. All rights reserved.
* This file is licensed under the Apache Software License, v. 2 except as noted
* otherwise in the LICENSE file
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

// Package memoryfs provides a memory based virtual filesystem implementation.
// The complete filesystem structure is kept in memory.
package memoryfs
20 changes: 20 additions & 0 deletions pkg/osfs/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/*
* Copyright 2020 Mandelsoft. All rights reserved.
* This file is licensed under the Apache Software License, v. 2 except as noted
* otherwise in the LICENSE file
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

// Package osfs maps the operating system filesystem to a virtual filesystem.
package osfs
2 changes: 1 addition & 1 deletion pkg/osfs/tempfs.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ import (
"io/ioutil"
"os"

"github.com/mandelsoft/vfs/pkg/vfs"
"github.com/mandelsoft/vfs/pkg/projectionfs"
"github.com/mandelsoft/vfs/pkg/vfs"
)

type tempfs struct {
Expand Down
21 changes: 21 additions & 0 deletions pkg/projectionfs/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*
* Copyright 2020 Mandelsoft. All rights reserved.
* This file is licensed under the Apache Software License, v. 2 except as noted
* otherwise in the LICENSE file
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

// Package projectionfs implements virtual filesystems based on a
// dedicated directory of a base filesystem.
package projectionfs
20 changes: 20 additions & 0 deletions pkg/readonlyfs/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/*
* Copyright 2020 Mandelsoft. All rights reserved.
* This file is licensed under the Apache Software License, v. 2 except as noted
* otherwise in the LICENSE file
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

// Package readonlyfs provides a read-only view of a base filesystem.
package readonlyfs
39 changes: 39 additions & 0 deletions pkg/yamlfs/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* Copyright 2020 Mandelsoft. All rights reserved.
* This file is licensed under the Apache Software License, v. 2 except as noted
* otherwise in the LICENSE file
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

// Package yamlfs provides a virtual filesystem based on the structure and
// content of a yaml document.
//
// Hereby maps are used to represent the directory hierarchy. Content of
// a field will be offered as file content.
// To represent more complex cases a map inclusing the field `$type` is
// not interpreted as directory by default, but according to the
// value of the type attribute.
// - type `directory`: the field `value` is used a directory content
// - type `file`: the field `value` is used as file content
// - type `symlink`: the field `value` is used symlink content
// - type `yaml`: the field `value` is used to provide file content
// that is provided as yaml file data (read and write)
// - type `json`: the field `value` is used to provide file content
// that is provided as json file data (read and write)
//
// string data starting with a line `---Start Binary---`and finished with a
// line ` ---End Binary---` interpretes the data in-between as bas64 encoded
// binary data. The latest version is able to handle binary data directly
// as described by the yaml format for reading and writing.
package yamlfs
8 changes: 7 additions & 1 deletion pkg/yamlfs/filedata.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ const typeSYMLINK = "symlink"
const typeYAML = "yaml"
const typeJSON = "json"

var UseStandardYAMLBinary = true

func validType(t string) bool {
switch t {
case typeDIR, typeSYMLINK, typeYAML, typeJSON:
Expand Down Expand Up @@ -345,13 +347,17 @@ func ToBinary(data interface{}) []byte {
return []byte(err.Error())
}
return d
case []byte:
return e
default:
return []byte(fmt.Sprintf("%s", e))

}
}

func FromBinary(data []byte) interface{} {
if UseStandardYAMLBinary {
return string(data)
}
b := base64.StdEncoding.EncodeToString(data)
n := "\n"
for len(b) > 120 {
Expand Down
Loading

0 comments on commit 4781252

Please sign in to comment.