Skip to content

Commit d03d33d

Browse files
committed
copy tree + folder to memory yamlfs generator
1 parent 4781252 commit d03d33d

File tree

7 files changed

+175
-8
lines changed

7 files changed

+175
-8
lines changed

README.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,6 @@ the package `os` by the instance of the virtual filesystem.
5555
return nil, err
5656
}
5757
defer f.Close()
58-
vfs.ReadFile()
5958
return ioutil.ReadAll(f)
6059
```
6160

cmd/yamlfs/main.go

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
/*
2+
* Copyright 2020 Mandelsoft. All rights reserved.
3+
* This file is licensed under the Apache Software License, v. 2 except as noted
4+
* otherwise in the LICENSE file
5+
*
6+
* Licensed under the Apache License, Version 2.0 (the "License");
7+
* you may not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
19+
package main
20+
21+
import (
22+
"flag"
23+
"fmt"
24+
"io/ioutil"
25+
"os"
26+
"strconv"
27+
28+
"github.com/mandelsoft/vfs/pkg/osfs"
29+
"github.com/mandelsoft/vfs/pkg/vfs"
30+
"github.com/mandelsoft/vfs/pkg/yamlfs"
31+
)
32+
33+
type Config struct {
34+
Go bool
35+
Name string
36+
Pkg string
37+
Copyright string
38+
}
39+
40+
func ExitOnError(err error) {
41+
if err != nil {
42+
fmt.Fprintf(os.Stderr, "Error: %s\n", err)
43+
os.Exit(1)
44+
}
45+
}
46+
47+
func main() {
48+
var opts Config
49+
flag.BoolVar(&opts.Go, "go", false, "generate a go file instead of a yaml file")
50+
flag.StringVar(&opts.Name, "name", "YamlFS", "The go variable name to use")
51+
flag.StringVar(&opts.Pkg, "package", "gofs", "Package name to use")
52+
flag.StringVar(&opts.Copyright, "copyright", "", "Package copyright header")
53+
flag.Parse()
54+
args := flag.Args()
55+
56+
srcDir := "."
57+
dstDir := vfs.PathSeparatorString
58+
if len(args) > 0 {
59+
if len(args) > 1 {
60+
if len(args) > 2 {
61+
ExitOnError(fmt.Errorf("too many arguments"))
62+
}
63+
dstDir = args[1]
64+
}
65+
srcDir = args[0]
66+
}
67+
dst, err := yamlfs.New(nil)
68+
ExitOnError(err)
69+
src := osfs.New()
70+
ExitOnError(vfs.CopyDir(src, srcDir, dst, dstDir))
71+
data, err := dst.Data()
72+
ExitOnError(err)
73+
if opts.Go {
74+
copyright := ""
75+
if opts.Copyright != "" {
76+
data, err := ioutil.ReadFile(opts.Copyright)
77+
ExitOnError(err)
78+
copyright = string(data) + "\n"
79+
}
80+
fmt.Printf(`%spackage %s
81+
82+
import (
83+
"github.com/mandelsoft/vfs/pkg/yamlfs"
84+
)
85+
86+
func New%s() *yamlfs.YamlFileSystem {
87+
fs, _ := yamlfs.New([]byte(%s))
88+
return fs
89+
}
90+
91+
`, copyright, opts.Pkg, opts.Name, strconv.Quote(string(data)))
92+
} else {
93+
fmt.Printf("%s\n", data)
94+
}
95+
}

go.mod

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,11 @@ module github.com/mandelsoft/vfs
33
go 1.13
44

55
require (
6+
github.com/b4b4r07/go-pipe v0.0.0-20191010045404-84b446f57366 // indirect
7+
github.com/joncalhoun/pipe v0.0.0-20170510025636-72505674a733 // indirect
68
github.com/mandelsoft/filepath v0.0.0-20200909114706-3df73d378d55
79
github.com/onsi/ginkgo v1.14.0
810
github.com/onsi/gomega v1.10.1
11+
gopkg.in/pipe.v2 v2.0.0-20140414041502-3c2ca4d52544 // indirect
912
gopkg.in/yaml.v2 v2.3.0
1013
)

go.sum

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
github.com/b4b4r07/go-pipe v0.0.0-20191010045404-84b446f57366 h1:FVAkDbBxovi2ID0vaxY7vCGvdKASt9r0TGPM1u4YQyg=
2+
github.com/b4b4r07/go-pipe v0.0.0-20191010045404-84b446f57366/go.mod h1:1ymsiQNa3qebVEEVtuIdhtAXRfjO4qFCFq1bBUOT2HE=
13
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
24
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
35
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
@@ -12,6 +14,8 @@ github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw
1214
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
1315
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
1416
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
17+
github.com/joncalhoun/pipe v0.0.0-20170510025636-72505674a733 h1:/wtaMDeVpoAUkqZl/GT3lvM9nDBmRApu/Uvl7EUc9Ao=
18+
github.com/joncalhoun/pipe v0.0.0-20170510025636-72505674a733/go.mod h1:2MNFZhLx2HMHTN4xKH6FhpoQWqmD8Ato8QOE2hp5hY4=
1519
github.com/mandelsoft/filepath v0.0.0-20180115145118-e79b4e7be206 h1:M02UJfGz1+m1oecAZ0JR3vtYmIHWGjzeiB979dDYrD0=
1620
github.com/mandelsoft/filepath v0.0.0-20180115145118-e79b4e7be206/go.mod h1:EG0hGSztMG2F0cd5TYTQeCCB2hSJIAom3QuR7zgKMzE=
1721
github.com/mandelsoft/filepath v0.0.0-20200901163143-eceff1ab880a h1:MrULybu0xBqZb/VfEJNnyhkBBmBLZ4iKsWhYIfV18YE=
@@ -62,6 +66,8 @@ google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzi
6266
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
6367
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
6468
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
69+
gopkg.in/pipe.v2 v2.0.0-20140414041502-3c2ca4d52544 h1:WJH1qsOB4/zb/li+zLMn0vaAUJ5FqPv6HYLI3aQVg1k=
70+
gopkg.in/pipe.v2 v2.0.0-20140414041502-3c2ca4d52544/go.mod h1:UhTeH/yXCK/KY7TX24mqPkaQ7gZeqmWd/8SSS8B3aHw=
6571
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
6672
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
6773
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=

pkg/composefs/compose.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,11 @@ func (c *ComposedFileSystem) Mount(path string, fs vfs.FileSystem) error {
135135
if !fi.IsDir() {
136136
return fmt.Errorf("mount failed: mount point %s must be dir", mountp)
137137
}
138+
for p := range c.mounts {
139+
if p == mountp || strings.Contains(p, mountp+vfs.PathSeparatorString) {
140+
delete(c.mounts, p)
141+
}
142+
}
138143
c.mounts[mountp] = fs
139144
return nil
140145
}

pkg/vfs/utils.go

Lines changed: 65 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -385,7 +385,71 @@ func CopyFile(srcfs FileSystem, src string, dstfs FileSystem, dst string) error
385385
defer d.Close()
386386

387387
_, err = io.Copy(d, s)
388-
return err
388+
if err != nil {
389+
return err
390+
}
391+
return dstfs.Chmod(dst, fi.Mode())
392+
}
393+
394+
// CopyDir recursively copies a directory tree, attempting to preserve permissions.
395+
// Source directory must exist, destination directory may exist.
396+
// Symlinks are ignored and skipped.
397+
func CopyDir(srcfs FileSystem, src string, dstfs FileSystem, dst string) error {
398+
src = Trim(srcfs, src)
399+
dst = Trim(dstfs, dst)
400+
401+
si, err := srcfs.Stat(src)
402+
if err != nil {
403+
return err
404+
}
405+
if !si.IsDir() {
406+
return NewPathError("CopyDir", src, ErrNotDir)
407+
}
408+
409+
di, err := dstfs.Stat(dst)
410+
if err != nil && !os.IsNotExist(err) {
411+
return err
412+
}
413+
if err == nil && !di.IsDir() {
414+
return NewPathError("CopyDir", dst, ErrNotDir)
415+
}
416+
417+
err = dstfs.MkdirAll(dst, si.Mode())
418+
if err != nil {
419+
return err
420+
}
421+
422+
entries, err := ReadDir(srcfs, src)
423+
if err != nil {
424+
return err
425+
}
426+
427+
for _, entry := range entries {
428+
srcPath := Join(srcfs, src, entry.Name())
429+
dstPath := Join(dstfs, dst, entry.Name())
430+
431+
if entry.IsDir() {
432+
err = CopyDir(srcfs, srcPath, dstfs, dstPath)
433+
} else {
434+
// Skip symlinks.
435+
if entry.Mode()&os.ModeSymlink != 0 {
436+
var old string
437+
old, err = srcfs.Readlink(srcPath)
438+
if err == nil {
439+
err = dstfs.Symlink(old, dstPath)
440+
}
441+
if err == nil {
442+
err = os.Chmod(dst, entry.Mode())
443+
}
444+
} else {
445+
err = CopyFile(srcfs, srcPath, dstfs, dstPath)
446+
}
447+
}
448+
if err != nil {
449+
return err
450+
}
451+
}
452+
return nil
389453
}
390454

391455
func Touch(fs FileSystem, path string, perm os.FileMode) error {

pkg/yamlfs/yamlfs.go

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -47,16 +47,11 @@ func New(data []byte) (*YamlFileSystem, error) {
4747
func NewByPath(fs vfs.FileSystem, path string) (*YamlFileSystem, error) {
4848
var data []byte
4949
var err error
50-
var f vfs.File
5150

5251
if fs == nil {
5352
data, err = ioutil.ReadFile(path)
5453
} else {
55-
f, err = fs.Open(path)
56-
if err == nil {
57-
defer f.Close()
58-
data, err = ioutil.ReadAll(f)
59-
}
54+
data, err = vfs.ReadFile(fs, path)
6055
}
6156
if err != nil {
6257
return nil, err

0 commit comments

Comments
 (0)