-
Notifications
You must be signed in to change notification settings - Fork 77
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow parsing module from any filesystem #49
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
package tfconfig | ||
|
||
import ( | ||
"io/ioutil" | ||
"os" | ||
) | ||
|
||
// FS represents a minimal filesystem implementation | ||
// See io/fs.FS in http://golang.org/s/draft-iofs-design | ||
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 | ||
// See io/fs.File in http://golang.org/s/draft-iofs-design | ||
type File interface { | ||
Stat() (os.FileInfo, error) | ||
Read([]byte) (int, error) | ||
Close() error | ||
} | ||
|
||
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{} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,19 +13,29 @@ import ( | |
ctyjson "github.com/zclconf/go-cty/cty/json" | ||
) | ||
|
||
func loadModule(dir string) (*Module, Diagnostics) { | ||
func loadModule(fs FS, dir string) (*Module, Diagnostics) { | ||
mod := newModule(dir) | ||
primaryPaths, diags := dirFiles(dir) | ||
primaryPaths, diags := dirFiles(fs, dir) | ||
|
||
parser := hclparse.NewParser() | ||
|
||
for _, filename := range primaryPaths { | ||
var file *hcl.File | ||
var fileDiags hcl.Diagnostics | ||
|
||
b, err := fs.ReadFile(filename) | ||
if err != nil { | ||
diags = append(diags, &hcl.Diagnostic{ | ||
Severity: hcl.DiagError, | ||
Summary: "Failed to read file", | ||
Detail: fmt.Sprintf("The configuration file %q could not be read.", filename), | ||
}) | ||
continue | ||
} | ||
if strings.HasSuffix(filename, ".json") { | ||
file, fileDiags = parser.ParseJSONFile(filename) | ||
file, fileDiags = parser.ParseJSON(b, filename) | ||
} else { | ||
file, fileDiags = parser.ParseHCLFile(filename) | ||
file, fileDiags = parser.ParseHCL(b, filename) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These original It's just filename-based cache and so in order to get a hit we'd need two duplicate files in a directory, which is unlikely to ever happen anyway, so this change should in that sense be harmless and shouldn't affect performance in any way. |
||
} | ||
diags = append(diags, fileDiags...) | ||
if file == nil { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This error matches the one from
ParseHCLFile
: https://github.com/hashicorp/hcl/blob/350d663f3c09e5a6d72ca11cb3250c1ce395bc8f/hclparse/parser.go#L70-L79There is a small drift from
ParseJSONFile
in thatjson.ParseFile
first opens the file and reports early diagnostic from there. This difference seems insignificant to me, but I'm open to retrofitting the extraOpen
call with that extra dedicated diagnostic here if deemed necessary.