-
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
Changes from 5 commits
cca4db6
0c87717
84a4848
4dd0f23
655a236
548e43e
48f3154
d12b69b
549affb
a66383b
be15f49
a1b1b33
caece11
36d2d4f
ffc95e9
82690f1
c19afee
ce1359c
251ddef
cbe799f
58fbc92
2b505fc
312d5bd
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 |
---|---|---|
|
@@ -8,7 +8,7 @@ to [Examples](../tutorials/examples.md). | |
On the | ||
other hand, if you are a developer and wish to | ||
learn more about the formal grammar underlying | ||
_l2_, visit the [Grammar](../reference/grammar.md) | ||
*l2*, visit the [Grammar](../reference/grammar.md) | ||
section. | ||
|
||
### Comments start with `#` | ||
|
@@ -80,10 +80,34 @@ Cookies are specified in a `Cookie` header as follows: | |
Cookie:'sessionid=foo;another-cookie=bar' | ||
``` | ||
|
||
### API variables can be defined in `apirequest.l2` | ||
|
||
L2 uses the variables declared inside the `.l2` file and makes the request | ||
|
||
Example `login.l2`: | ||
|
||
``` | ||
let REMOTE = "httpbin.org" | ||
let EMAIL = "[email protected]" | ||
|
||
--- | ||
|
||
POST | ||
${REMOTE}/login | ||
{ | ||
"email": "${EMAIL}", | ||
"password": "[email protected]" | ||
} | ||
``` | ||
|
||
Get [Source Files](https://github.com/HexmosTech/Lama2/tree/main/examples/0021_varjson_variable/0021_varjson_variable.l2) | ||
|
||
|
||
### API environment variables can be defined locally in `l2.env` | ||
|
||
By default, *l2* looks for a `l2.env` file in the same directory as the given | ||
request file directory. Example `l2.env`: | ||
`l2.env` is searched for, from the present directory and variables(local) are loaded from this file. | ||
|
||
Example `l2.env`: | ||
|
||
``` | ||
export PHOTO=`base64 aadhaarlarge.jpg` | ||
|
@@ -92,10 +116,9 @@ export AHOST="http://localhost:8000" | |
|
||
Get [Source Files](https://github.com/HexmosTech/Lama2/tree/main/examples/0004_env_switch_root) | ||
|
||
### API environment variables can be defined at project level using `l2config.env` | ||
|
||
_l2_ loads local variables from `l2.env`. | ||
If not found then uses variables from `l2config.env`. | ||
### API environment variables can be defined at root using `l2config.env` | ||
`l2config.env` is searched for, from the present directory to all its ancestors (upto `/`) and | ||
variables(root) are loaded from this file. | ||
Example `l2config.env`: | ||
|
||
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. Screenshot needed to show project structure, and root. |
||
``` | ||
|
@@ -105,12 +128,15 @@ export AHOST="http://localhost:8001" | |
|
||
Get [Source Files](https://github.com/HexmosTech/Lama2/tree/main/examples/0019_env_switch_global_root) | ||
|
||
### If API environment variables are locally and at project level | ||
### If `l2config.env`(root) variables are redeclared in `l2.env`(local) | ||
|
||
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 commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
|
||
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. Must show full example here. 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. ok |
||
Get [Source Files](https://github.com/HexmosTech/Lama2/tree/main/examples/0020_override_project_root_local) | ||
|
||
![Override of l2config.env with l2.env variable](image.png) | ||
|
||
|
||
#### The environment file can load results of commands | ||
|
||
Use the backtick notation `\`command\`` to place the results of | ||
|
@@ -124,7 +150,7 @@ One can load the `PHOTO` variable in API files. | |
|
||
### Chain requests through Javascript blocks | ||
|
||
_Lama2_ supports plain Javascript (JS) blocks | ||
*Lama2* supports plain Javascript (JS) blocks | ||
as a glue for manipulating responses and passing on | ||
values to later stages. At a higher | ||
level, a chain of requests may look like: | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
let REMOTE = "httpbin.org" | ||
let EMAIL = "[email protected]" | ||
|
||
--- | ||
|
||
POST | ||
${REMOTE}/login | ||
{ | ||
"email": "${EMAIL}", | ||
"password": "[email protected]" | ||
} | ||
|
||
--- | ||
|
||
let TOKEN = result['jwt'] | ||
|
||
--- | ||
|
||
POST | ||
${REMOTE}/logout | ||
"Authorization": "Bearer ${TOKEN}" | ||
{ | ||
"email": "${EMAIL}", | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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 commentThe 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 commentThe reason will be displayed to describe this comment to others. Learn more. It was erroring out in the make lint |
||
return source | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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 commentThe reason will be displayed to describe this comment to others. Learn more. Why comment this? If lines not needed, should be deleted. |
||
// } | ||
return s[:i], i | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -100,7 +100,7 @@ func ExpandJSON(block *gabs.Container, vm *goja.Runtime) { | |
} | ||
|
||
func SearchL2ConfigEnv(dir string) (string, error) { | ||
parentDir := filepath.Dir(dir) | ||
parentDir := dir | ||
for parentDir != string(filepath.Separator) { | ||
l2ConfigPath := filepath.Join(parentDir, "l2config.env") | ||
_, err := os.Stat(l2ConfigPath) | ||
|
@@ -116,7 +116,7 @@ func LoadEnvFile(l2path string) { | |
envFileName := filepath.Base(l2path) | ||
err := godotenv.Load(l2path) | ||
if err != nil { | ||
log.Info().Str("Type", "Preprocess").Msg("Didn't find "+ envFileName +" in the API directory") | ||
log.Info().Str("Type", "Preprocess").Msg("Didn't find " + envFileName + " in the API directory") | ||
} | ||
} | ||
|
||
|
@@ -153,30 +153,54 @@ func populateEnvMap(envMap map[string]map[string]interface{}, envPath string, so | |
return nil | ||
} | ||
|
||
func GetL2EnvVariables(dir string) ([]byte, error) { | ||
func getEnvMap(envPath string, source string) (map[string]map[string]interface{}, error) { | ||
envs, err := readFile(envPath) | ||
if err != nil { | ||
return nil, err | ||
} | ||
envMap := make(map[string]map[string]interface{}) | ||
for key, value := range envs { | ||
variable := make(map[string]interface{}) | ||
variable["val"] = value | ||
variable["src"] = source | ||
envMap[key] = variable | ||
} | ||
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 commentThe reason will be displayed to describe this comment to others. Learn more. Add a comment regarding desired order for |
||
finalEnvMap := make(map[string]map[string]interface{}) | ||
for _, envMap := range envMaps { | ||
for key, value := range envMap { | ||
finalEnvMap[key] = value | ||
} | ||
} | ||
return finalEnvMap | ||
} | ||
|
||
func GetL2EnvVariables(dir string) ([]byte, error) { | ||
l2ConfigPath, err := SearchL2ConfigEnv(dir) | ||
if err != nil { | ||
log.Error().Str("Type", "Preprocess").Msg(err.Error()) | ||
} else { | ||
err = populateEnvMap(finalEnvMap, l2ConfigPath, "l2configenv") | ||
if err != nil { | ||
log.Error().Str("Type", "Preprocess").Msg(err.Error()) | ||
} | ||
return nil, err | ||
} | ||
l2ConfigEnvMap, err := getEnvMap(l2ConfigPath, "l2configenv") | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
l2EnvPath := path.Join(dir, "l2.env") | ||
err = populateEnvMap(finalEnvMap, l2EnvPath, "l2env") | ||
l2EnvMap, err := getEnvMap(l2EnvPath, "l2env") | ||
if err != nil { | ||
log.Error().Str("Type", "Preprocess").Msg(err.Error()) | ||
return nil, err | ||
} | ||
|
||
finalEnvMap := combineEnvMaps(l2ConfigEnvMap, l2EnvMap) | ||
|
||
jsonEnvs, err := json.MarshalIndent(finalEnvMap, "", " ") | ||
if err != nil { | ||
log.Error().Str("Type", "Preprocess").Msg("Failed to marshal map env's to JSON: " + err.Error()) | ||
return nil, err | ||
return nil, fmt.Errorf("Failed to marshal map env's to JSON: %v", err) | ||
} | ||
|
||
return jsonEnvs, 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.
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.
Yes works.