-
Notifications
You must be signed in to change notification settings - Fork 6
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
Global variable support and Generate env JSON option #24
Conversation
After every documentation change - we are supposed to run the following and commit all resultant files:
Anyway - wait till my overall review finishes, then you can do this. |
@@ -69,8 +69,18 @@ Get [Source File](https://github.com/HexmosTech/Lama2/tree/main/examples/0003_co | |||
|
|||
## Environment Variables: Switch base URL | |||
|
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.
We can make the documentation more structured (something like this)
Case 1: l2.env
adjacent to an API file
For any given .l2
file, one can place an l2.env
file to store relevant variables. These variables will be available to be used within the API file
[example]
Case 2: Project-level variables
In Lama2, you can have a large number of API files stored in a hierarchical folder configuration. The root of such a project can be signified through l2config.env
:
[API Hub folder screenshot with l2config.env
highlighted]
Within such a structure, you can have an API file anywhere, which can use variables defined in the project-level variables:
[Example l2config.env and api.l2 with appropriate folder structure; the example must be hosted in Lama2 repo (see other examples)]
Case 3: Override Project-level variable with local variable
....
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.
Got it
@@ -67,7 +67,7 @@ func GetLamaFileAsString(path string) string | |||
func LamaFile(inputFile string) (string, string) | |||
``` | |||
|
|||
LamaFile takes in a path to an API file. It moves into the API file directory, reads the API contents, loads the \`l2.env\` file if available, and finally substitutes environment vars in the API contents Once done, it reverts back to the original directory, and returns the processed l2 file. | |||
LamaFile takes in a path to an API file. It moves into the API file directory, reads the API contents, loads the \`l2config.env\` global variables file if available in any of parent directory and \`l2.env\` file if available in present directory , and finally substitutes environment vars in the API contents Once done, it reverts back to the original directory, and returns the processed l2 file. |
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.
Comment can make the "overwriting" part more obvious. Sentence is too long now, maybe simplify a bit.
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.
Yes
@@ -48,7 +48,7 @@ From a high level, how does it work now? | |||
2. Else if block is Requestor block | |||
1. Replace variables with values in the following order | |||
1. Try fetch variable from Javascript VM | |||
2. If (1) fails, try fetch variable from `l2.env` | |||
2. If (1) fails, try fetch variable from `l2config.env` and `l2.env` |
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.
"overwriting" is an implementation detail. When you talk to users - how does it work?
- JS VM variable
- Local env variable
- l2config env variable.
Always explain in this way. The implementation detail doesn't matter at documentation/explanation level.
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.
Okay got it
@@ -83,6 +83,17 @@ Cookies are specified in a `Cookie` header as follows: | |||
Cookie:'sessionid=foo;another-cookie=bar' | |||
``` | |||
|
|||
### Global Environments variables/commands can be defined in `/l2config.env/<requests_dir>` | |||
|
|||
The *l2* loads up variables from `l2config.env` and then `l2.env`. |
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.
Again - the overwrite explanation is more complex to the reader/user. Simply say what order in which variables are searched for (nearest first):
- VM
- local
- global
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.
Either:
The l2 binary loads...
or
l2
loads
@@ -83,6 +83,17 @@ Cookies are specified in a `Cookie` header as follows: | |||
Cookie:'sessionid=foo;another-cookie=bar' | |||
``` | |||
|
|||
### Global Environments variables/commands can be defined in `/l2config.env/<requests_dir>` |
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.
Instead of calling it "global", I think we should call it something like:
- Project-level variables
- Root variables
- Project-root variables
Let's pick one of the above and finalize (or make other suggestions).
Second, I think we should use git
repo analogy to explain.
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.
I have added the git repo analogy in example.md, should I link it here as well?
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.
Analogy should be in the explanation section, not example section. When confused what belongs where, re-read this
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.
Yes
@@ -83,6 +83,17 @@ Cookies are specified in a `Cookie` header as follows: | |||
Cookie:'sessionid=foo;another-cookie=bar' | |||
``` | |||
|
|||
### Global Environments variables/commands can be defined in `/l2config.env/<requests_dir>` |
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.
Global Environments variables/commands can be defined in
/l2config.env/<requests_dir>
Title is a bit clumsy.
API environment variables can be defined at project level using
l2config.env
Is much simpler.
Remaining comments - I think we still do not have functionality for obtaining the variable suggestions from VSCode (using some CLI switch - pls make proposals). That can be added to this MR itself. |
In general - nice first MR π |
Also - we must add test case(s) for this new logic. |
- Command to get the envs `l2 --env ${l2FilePath}`. - All the envs of l2config.env is fetched and overwritten by l2.env. - Creates a JSON of all the envs with its value and source of origin.
The description has to be more precise.
|
|
||
### API environment variables can be defined at project level using `l2config.env` | ||
|
||
_l2_ loads local variables from `l2.env`. |
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 is confusing to the end user. You mean - at file level or at variable?
The fact is, we load variables from both files. If there is ever a conflict in a particular variable name, the way prioritize selection is:
- VM vars
l2.env
varsl2config.env
vars
_l2_ loads local variables from `l2.env`. | ||
If not found then uses variables from `l2config.env`. | ||
Example `l2config.env`: | ||
|
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.
Screenshot needed to show project structure, and root.
### If API environment variables are locally and at project level | ||
|
||
The local variable's value is taken into consideration | ||
|
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.
Must show full example here.
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.
ok
preprocess/preprocess.go
Outdated
@@ -96,11 +99,85 @@ func ExpandJSON(block *gabs.Container, vm *goja.Runtime) { | |||
log.Debug().Str("Processed JSON block", block.String()).Msg("") | |||
} | |||
|
|||
func LoadElfEnv(l2path string) { | |||
func SearchL2ConfigEnv(dir string) (string, error) { | |||
parentDir := filepath.Dir(dir) |
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.
We should start from present folder itself. What if it is a project without any subdirs.
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.
Yeah this case failed :(
return | ||
} | ||
defer file.Close() | ||
return godotenv.Parse(file) |
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.
One thing to verify is - does this properly handle back-tick commands?
Say I have an echo statement or something, is it going to do the right thing?
Are our test cases checking this case?
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.
Like this in the l2.env file ?
export ECHO_CMD="`echo "base64 image.jpeg"`"
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.
export PHOTO=`base64 image.jpeg`
?
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.
yes, the photo case must work (check tests/examples).
in general, the backticks can have any arbitrary linux command - which runs first, and then the output is stored in the env variable.
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.
No there is no test on that, will add
return err | ||
} | ||
for key, value := range envs { | ||
variable := make(map[string]interface{}) |
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.
8 spaces? use the gofumpt
or some other thing in the makefile to format.
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.
You can run both of these and make any mods:
lint:
golangci-lint run --disable-all -E revive ./...
gofumpt:
gofumpt -w .
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.
ok
preprocess/preprocess.go
Outdated
if err != nil { | ||
log.Error().Str("Type", "Preprocess").Msg(err.Error()) | ||
} else { | ||
err = populateEnvMap(finalEnvMap, l2ConfigPath, "l2configenv") |
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 function is confusing. Try to write a pure functions:
- explicit inputs
- no modification of inputs
- clear outputs (new variables)
- reassign outputs here
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.
Yes removed the finalMap modifying part.
Removing populateFinalENv() Adding getEnvMap()
l2format.md architecture.md preperocess.md examples.md
log.Info().Str("Type", "Preprocess").Msg("Env Variables:\n" + string(jsonEnvs)) | ||
return | ||
// Frontend can read the stdout for this command and get the JSON of all the env's | ||
fmt.Println(string(jsonEnvs)) |
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.
Just check that with verbose
mode as well - this works. I think we have a -v
and -vv
option IIRC.
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.
|
||
The local variable's value is taken into consideration | ||
The local variable's value is taken into consideration regardless of both files reside in same directory |
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.
*residing
preprocess/expandvar.go
Outdated
@@ -114,8 +114,8 @@ func getShellName(s string) (string, int) { | |||
} | |||
// Scan alphanumerics. | |||
var i int | |||
for i = 0; i < len(s) && isAlphaNum(s[i]); i++ { | |||
} | |||
// for i = 0; i < len(s) && isAlphaNum(s[i]); i++ { |
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.
Why comment this? If lines not needed, should be deleted.
return envMap, nil | ||
} | ||
|
||
func combineEnvMaps(envMaps ...map[string]map[string]interface{}) map[string]map[string]interface{} { |
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.
Add a comment regarding desired order for l2config.env
and l2.env
in this case. What overwrites what?
This has not been addressed @lovestaco |
- Making changes in the Documentation.
|
parser/jsonparser.go
Outdated
@@ -25,7 +25,7 @@ func (p *Lama2Parser) PrimitiveType() (*gabs.Container, error) { | |||
|
|||
// CustomPairMerge uses a gabs feature to deal with merge conflicts. | |||
// More here: https://github.com/HexmosTech/gabs/blob/master/gabs.go#L511 | |||
func CustomPairMerge(destination, source interface{}) interface{} { | |||
func CustomPairMerge(_, source interface{}) interface{} { |
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.
Why rename this in jsonparser?
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.
It was erroring out in the make lint
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.
LGTM π₯³
What type of MR is this?
Description
This MR adds the feature of supporting global variables.
Edit1:
L2 can now fetch variables declared in
l2config.env
which can be in the parent directory.l2config.env
is searched for, from the present directory to all its ancestors (upto/
).A directory may have both
l2.env
ANDl2config.env
Edit2:
l2 --env <l2FilePath>
.Important code file to start Code Review from
controller.go
Added tests?
Added to documentation?