lang: Pass through the Fs and the FsURI

This should give us options as to how a function should interact with an
FS. I feel like it's cleaner to go through the World API, and passing in
the FsURI lets us do that, but I passed in the Fs at the same time in
case it's useful for some reason. I think using it is a boundary
violation, but it's just a hunch. Does anything break when we move from
one deploy to the next?
This commit is contained in:
James Shubin
2019-07-23 01:26:00 -04:00
parent 4b6b91c08b
commit 066048f4de
8 changed files with 47 additions and 9 deletions

View File

@@ -234,8 +234,10 @@ func (obj *GAPI) Cli(cliInfo *gapi.CliInfo) (*gapi.Deploy, error) {
logf("init...")
// init and validate the structure of the AST
data := &interfaces.Data{
Fs: localFs, // the local fs!
Base: output.Base, // base dir (absolute path) that this is rooted in
// TODO: add missing fields here if/when needed
Fs: localFs, // the local fs!
FsURI: localFs.URI(), // TODO: is this right?
Base: output.Base, // base dir (absolute path) that this is rooted in
Files: output.Files,
Imports: importVertex,
Metadata: output.Metadata,
@@ -415,6 +417,7 @@ func (obj *GAPI) LangInit() error {
obj.lang = &Lang{
Fs: fs,
FsURI: obj.InputURI,
Input: input,
Hostname: obj.data.Hostname,
@@ -671,8 +674,10 @@ func (obj *GAPI) Get(getInfo *gapi.GetInfo) error {
logf("init...")
// init and validate the structure of the AST
data := &interfaces.Data{
Fs: localFs, // the local fs!
Base: output.Base, // base dir (absolute path) that this is rooted in
// TODO: add missing fields here if/when needed
Fs: localFs, // the local fs!
FsURI: localFs.URI(), // TODO: is this right?
Base: output.Base, // base dir (absolute path) that this is rooted in
Files: output.Files,
Imports: importVertex,
Metadata: output.Metadata,

View File

@@ -142,6 +142,10 @@ type Data struct {
// system to manage file resources or other aspects.
Fs engine.Fs
// FsURI is the fs URI of the active filesystem. This is useful to pass
// to the engine.World API for further consumption.
FsURI string
// Base directory (absolute path) that the running code is in. If an
// import is found, that's a recursive addition, and naturally for that
// run, this value would be different in the recursion.

View File

@@ -115,6 +115,16 @@ type NamedArgsFunc interface {
// TODO: Consider combining this with the existing Data struct or more of it...
// TODO: Do we want to add line/col/file values here, and generalize this?
type FuncData struct {
// Fs represents a handle to the filesystem that we're running on. This
// is necessary for opening files if needed by import statements. The
// file() paths used to get templates or other files from our deploys
// come from here, this is *not* used to interact with the host file
// system to manage file resources or other aspects.
Fs engine.Fs
// FsURI is the fs URI of the active filesystem. This is useful to pass
// to the engine.World API for further consumption.
FsURI string
// Base directory (absolute path) that the running code is in. This is a
// copy of the value from the Expr and Stmt Data struct for Init.

View File

@@ -389,6 +389,7 @@ func TestInterpolateBasicStmt(t *testing.T) {
ast, fail, exp := tc.ast, tc.fail, tc.exp
data := &interfaces.Data{
// TODO: add missing fields here if/when needed
Debug: testing.Verbose(), // set via the -test.v flag to `go test`
Logf: func(format string, v ...interface{}) {
t.Logf("ast: "+format, v...)
@@ -711,6 +712,7 @@ func TestInterpolateBasicExpr(t *testing.T) {
ast, fail, exp := tc.ast, tc.fail, tc.exp
data := &interfaces.Data{
// TODO: add missing fields here if/when needed
Debug: testing.Verbose(), // set via the -test.v flag to `go test`
Logf: func(format string, v ...interface{}) {
t.Logf("ast: "+format, v...)

View File

@@ -441,6 +441,7 @@ func TestAstFunc0(t *testing.T) {
t.Logf("test #%d: AST: %+v", index, ast)
data := &interfaces.Data{
// TODO: add missing fields here if/when needed
Debug: testing.Verbose(), // set via the -test.v flag to `go test`
Logf: func(format string, v ...interface{}) {
t.Logf("ast: "+format, v...)
@@ -790,7 +791,9 @@ func TestAstFunc1(t *testing.T) {
importGraph.AddVertex(importVertex)
data := &interfaces.Data{
// TODO: add missing fields here if/when needed
Fs: fs,
FsURI: fs.URI(), // TODO: is this right?
Base: output.Base, // base dir (absolute path) the metadata file is in
Files: output.Files, // no really needed here afaict
Imports: importVertex,
@@ -1232,9 +1235,11 @@ func TestAstFunc2(t *testing.T) {
importGraph.AddVertex(importVertex)
data := &interfaces.Data{
// TODO: add missing fields here if/when needed
Fs: fs,
Base: output.Base, // base dir (absolute path) the metadata file is in
Files: output.Files, // no really needed here afaict
FsURI: "memmapfs:///", // we're in standalone mode
Base: output.Base, // base dir (absolute path) the metadata file is in
Files: output.Files, // no really needed here afaict
Imports: importVertex,
Metadata: output.Metadata,
Modules: "/" + interfaces.ModuleDirectory, // not really needed here afaict
@@ -1676,6 +1681,7 @@ func TestAstInterpret0(t *testing.T) {
t.Logf("test #%d: AST: %+v", index, ast)
data := &interfaces.Data{
// TODO: add missing fields here if/when needed
Debug: testing.Verbose(), // set via the -test.v flag to `go test`
Logf: func(format string, v ...interface{}) {
t.Logf("ast: "+format, v...)

View File

@@ -41,7 +41,9 @@ const (
// Lang is the main language lexer/parser object.
type Lang struct {
Fs engine.Fs // connected fs where input dir or metadata exists
Fs engine.Fs // connected fs where input dir or metadata exists
FsURI string
// Input is a string which specifies what the lang should run. It can
// accept values in several different forms. If is passed a single dash
// (-), then it will use `os.Stdin`. If it is passed a single .mcl file,
@@ -133,7 +135,9 @@ func (obj *Lang) Init() error {
obj.Logf("init...")
// init and validate the structure of the AST
data := &interfaces.Data{
// TODO: add missing fields here if/when needed
Fs: obj.Fs,
FsURI: obj.FsURI,
Base: output.Base, // base dir (absolute path) the metadata file is in
Files: output.Files,
Imports: importVertex,

View File

@@ -3241,7 +3241,9 @@ func (obj *StmtProg) importScopeWithInputs(s string, scope *interfaces.Scope, pa
logf("init...")
// init and validate the structure of the AST
data := &interfaces.Data{
// TODO: add missing fields here if/when needed
Fs: obj.data.Fs,
FsURI: obj.data.FsURI,
Base: output.Base, // new base dir (absolute path)
Files: files,
Imports: parentVertex, // the parent vertex that imported me
@@ -6690,7 +6692,9 @@ func (obj *ExprFunc) Init(data *interfaces.Data) error {
// TODO: do we want to pass in the full obj.data instead ?
if dataFunc, ok := obj.function.(interfaces.DataFunc); ok {
dataFunc.SetData(&interfaces.FuncData{
Base: obj.data.Base,
Fs: obj.data.Fs,
FsURI: obj.data.FsURI,
Base: obj.data.Base,
})
}
}
@@ -6776,7 +6780,9 @@ func (obj *ExprFunc) Copy() (interfaces.Expr, error) {
// TODO: do we want to pass in the full obj.data instead ?
if dataFunc, ok := function.(interfaces.DataFunc); ok {
dataFunc.SetData(&interfaces.FuncData{
Base: obj.data.Base,
Fs: obj.data.Fs,
FsURI: obj.data.FsURI,
Base: obj.data.Base,
})
}
copied = true

View File

@@ -836,6 +836,7 @@ func TestUnification1(t *testing.T) {
t.Logf("\n\ntest #%d: AST (before): %+v\n", index, ast)
data := &interfaces.Data{
// TODO: add missing fields here if/when needed
Debug: testing.Verbose(), // set via the -test.v flag to `go test`
Logf: func(format string, v ...interface{}) {
t.Logf(fmt.Sprintf("test #%d", index)+": ast: "+format, v...)