File: filesystem.go

package info (click to toggle)
golang-github-hashicorp-terraform-config-inspect 0.0~git20230614.f32df32-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 472 kB
  • sloc: makefile: 2
file content (117 lines) | stat: -rw-r--r-- 2,961 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0

package tfconfig

import (
	"io/fs"
	"io/ioutil"
	"os"
	"time"
)

// FS is an interface used by [LoadModuleFromFilesystem].
//
// Unfortunately this package implemented a draft version of the io/fs.FS
// API before it was finalized and so this interface is not compatible with
// the final design. To use this package with the final filesystem API design,
// use [WrapFS] to wrap a standard filesystem implementation so that it
// implements this interface.
type FS interface {
	Open(name string) (File, error)
	ReadFile(name string) ([]byte, error)
	ReadDir(dirname string) ([]os.FileInfo, error)
}

// File represents an open file in [FS].
type File interface {
	Stat() (os.FileInfo, error)
	Read([]byte) (int, error)
	Close() error
}

// wrapFS is a rather regrettable adapter from the standard library filesystem
// interfaces to the one we have designed in this package, since we adopted
// a draft of that API before it was finalized and the final is incompatible.
type wrapFS struct {
	wrapped fs.FS
}

// WrapFS wraps a standard library filesystem implementation so that it
// implements this package's own (slightly-incompatible) interface [FS].
func WrapFS(wrapped fs.FS) FS {
	return wrapFS{wrapped}
}

func (wfs wrapFS) Open(name string) (File, error) {
	return wfs.wrapped.Open(name)
}

func (wfs wrapFS) ReadFile(name string) ([]byte, error) {
	return fs.ReadFile(wfs.wrapped, name)
}

func (wfs wrapFS) ReadDir(dirname string) ([]os.FileInfo, error) {
	entries, err := fs.ReadDir(wfs.wrapped, dirname)
	var ret []os.FileInfo
	if len(entries) != 0 {
		ret = make([]os.FileInfo, len(entries))
		for i, entry := range entries {
			ret[i] = wrapFileInfoDirEntry{entry}
		}
	}
	return ret, err
}

type wrapFileInfoDirEntry struct {
	wrapped fs.DirEntry
}

func (d wrapFileInfoDirEntry) IsDir() bool {
	return d.wrapped.IsDir()
}

func (d wrapFileInfoDirEntry) ModTime() time.Time {
	// this package doesn't actually care about modification times,
	// so we don't need to implement this.
	panic("unimplemented")
}

func (d wrapFileInfoDirEntry) Mode() fs.FileMode {
	// this package doesn't actually care about file modes,
	// so we don't need to implement this.
	panic("unimplemented")
}

func (d wrapFileInfoDirEntry) Name() string {
	return d.wrapped.Name()
}

func (d wrapFileInfoDirEntry) Size() int64 {
	// this package doesn't actually care about file sizes,
	// so we don't need to implement this.
	panic("unimplemented")
}

func (d wrapFileInfoDirEntry) Sys() any {
	return nil
}

type osFs struct{}

func (fs *osFs) Open(name string) (File, error) {
	return os.Open(name)
}

func (fs *osFs) ReadFile(name string) ([]byte, error) {
	return ioutil.ReadFile(name)
}

func (fs *osFs) ReadDir(dirname string) ([]os.FileInfo, error) {
	return ioutil.ReadDir(dirname)
}

// NewOsFs provides a basic implementation of FS for an OS filesystem
func NewOsFs() FS {
	return &osFs{}
}