From cca4db69dd3483e1aa1ac41bc67781de51c8e265 Mon Sep 17 00:00:00 2001 From: lovestaco Date: Sun, 9 Jul 2023 20:41:54 +0530 Subject: [PATCH 01/23] search and load l2config.env file --- controller/controller.go | 1 + preprocess/preprocess.go | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/controller/controller.go b/controller/controller.go index 6131300d..52c75792 100644 --- a/controller/controller.go +++ b/controller/controller.go @@ -89,6 +89,7 @@ func Process(version string) { oldDir, _ := os.Getwd() utils.ChangeWorkingDir(dir) preprocess.LoadElfEnv(path.Join(dir, "l2.env")) + preprocess.LoadConfigEnv(path.Join(dir, "l2config.env")) utils.ChangeWorkingDir(oldDir) p := parser.NewLama2Parser() parsedAPI, e := p.Parse(apiContent) diff --git a/preprocess/preprocess.go b/preprocess/preprocess.go index 89de5372..7732d671 100644 --- a/preprocess/preprocess.go +++ b/preprocess/preprocess.go @@ -8,6 +8,7 @@ import ( "fmt" "io/ioutil" "os" + "path/filepath" "strings" "github.com/HexmosTech/gabs/v2" @@ -103,6 +104,25 @@ func LoadElfEnv(l2path string) { } } + +func LoadConfigEnv(l2ConfigPath string) { + err := godotenv.Load(l2ConfigPath) + if err != nil { + parentDir := filepath.Dir(l2ConfigPath) + for parentDir != string(filepath.Separator) { + l2ConfigPath = filepath.Join(parentDir, "l2config.env") + err = godotenv.Load(l2ConfigPath) + if err == nil { + log.Info().Str("Type", "Preprocess").Str("l2config.env found in", parentDir).Msg("") + return // Found the l2config.env file, exit the function + } + parentDir = filepath.Dir(parentDir) + } + log.Error().Str("Type", "Preprocess").Msg("Didn't find l2config.env in the API directory") + } +} + + func GetLamaFileAsString(path string) string { b, err := ioutil.ReadFile(path) // just pass the file name if err != nil { From 0c877179ae113c58f2f3172192b79383a47f2e34 Mon Sep 17 00:00:00 2001 From: lovestaco Date: Sun, 9 Jul 2023 20:53:15 +0530 Subject: [PATCH 02/23] consolidating LoadElfEnv and LoadConfigEnv --- controller/controller.go | 4 +--- preprocess/preprocess.go | 6 +++++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/controller/controller.go b/controller/controller.go index 52c75792..297e03ca 100644 --- a/controller/controller.go +++ b/controller/controller.go @@ -7,7 +7,6 @@ package contoller import ( "fmt" "os" - "path" "github.com/HexmosTech/gabs/v2" "github.com/HexmosTech/httpie-go" @@ -88,8 +87,7 @@ func Process(version string) { _, dir, _ := utils.GetFilePathComponents(o.Positional.LamaAPIFile) oldDir, _ := os.Getwd() utils.ChangeWorkingDir(dir) - preprocess.LoadElfEnv(path.Join(dir, "l2.env")) - preprocess.LoadConfigEnv(path.Join(dir, "l2config.env")) + preprocess.LoadEnvironments(dir) utils.ChangeWorkingDir(oldDir) p := parser.NewLama2Parser() parsedAPI, e := p.Parse(apiContent) diff --git a/preprocess/preprocess.go b/preprocess/preprocess.go index 7732d671..d7517206 100644 --- a/preprocess/preprocess.go +++ b/preprocess/preprocess.go @@ -8,6 +8,7 @@ import ( "fmt" "io/ioutil" "os" + "path" "path/filepath" "strings" @@ -104,7 +105,6 @@ func LoadElfEnv(l2path string) { } } - func LoadConfigEnv(l2ConfigPath string) { err := godotenv.Load(l2ConfigPath) if err != nil { @@ -122,6 +122,10 @@ func LoadConfigEnv(l2ConfigPath string) { } } +func LoadEnvironments(dir string) { + LoadElfEnv(path.Join(dir, "l2.env")) + LoadConfigEnv(path.Join(dir, "l2config.env")) +} func GetLamaFileAsString(path string) string { b, err := ioutil.ReadFile(path) // just pass the file name From 84a4848ab2e929b1318bbfa2bb78301f959595cc Mon Sep 17 00:00:00 2001 From: lovestaco Date: Mon, 10 Jul 2023 10:35:14 +0530 Subject: [PATCH 03/23] Adding comments for LoadEnvironments function --- preprocess/preprocess.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/preprocess/preprocess.go b/preprocess/preprocess.go index d7517206..e1f091f5 100644 --- a/preprocess/preprocess.go +++ b/preprocess/preprocess.go @@ -123,8 +123,8 @@ func LoadConfigEnv(l2ConfigPath string) { } func LoadEnvironments(dir string) { - LoadElfEnv(path.Join(dir, "l2.env")) - LoadConfigEnv(path.Join(dir, "l2config.env")) + LoadConfigEnv(path.Join(dir, "l2config.env")) // Loads global variables from l2config.env + LoadElfEnv(path.Join(dir, "l2.env")) // Overwrites the global variables if declared again in l2.env } func GetLamaFileAsString(path string) string { From 4dd0f23c6a1f7360fb26647ac8cd78ebbdeae87e Mon Sep 17 00:00:00 2001 From: lovestaco Date: Mon, 10 Jul 2023 10:35:47 +0530 Subject: [PATCH 04/23] Updating documentation with global variable support --- docs/Lama2/docs/explanation/l2format.md | 11 +++++++++++ docs/Lama2/docs/reference/architecture.md | 4 ++-- docs/Lama2/docs/reference/preprocess.md | 2 +- docs/Lama2/docs/tutorials/examples.md | 14 ++++++++++++-- 4 files changed, 26 insertions(+), 5 deletions(-) diff --git a/docs/Lama2/docs/explanation/l2format.md b/docs/Lama2/docs/explanation/l2format.md index 1a7c3f9c..41da8e6b 100644 --- a/docs/Lama2/docs/explanation/l2format.md +++ b/docs/Lama2/docs/explanation/l2format.md @@ -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/` + +The *l2* loads up variables from `l2config.env` and then `l2.env`. +If same variable is found in `l2.env` then overwrites the global variable. +Example `l2config.env`: + +``` +export PHOTO=`base64 aadhaarsmall.jpg` +export AHOST="http://localhost:8001" +``` + ### Environments variables/commands can be defined in `/l2.env` By default, *l2* looks for a `l2.env` file in the same directory as the given diff --git a/docs/Lama2/docs/reference/architecture.md b/docs/Lama2/docs/reference/architecture.md index a4ae5fd7..83035e8f 100644 --- a/docs/Lama2/docs/reference/architecture.md +++ b/docs/Lama2/docs/reference/architecture.md @@ -5,7 +5,7 @@ graph TD K["Controller Entry
(controller)"] A["Parse CLI
(lama2cmd)"] - B["Parser
(parser)"] + B["Parser
(parser)"] D["Request Executor
(cmdexec)"] E["Output Format Manager
(outputmanager)"] F["Error Reporting (TODO)"] @@ -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` 2. Use the processed elements to create an httpie-go request 3. Fetch response 5. If necessary, write the last transaction to `.json` file \ No newline at end of file diff --git a/docs/Lama2/docs/reference/preprocess.md b/docs/Lama2/docs/reference/preprocess.md index 14b0557a..6e04c18d 100644 --- a/docs/Lama2/docs/reference/preprocess.md +++ b/docs/Lama2/docs/reference/preprocess.md @@ -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. ## func [LoadElfEnv]() diff --git a/docs/Lama2/docs/tutorials/examples.md b/docs/Lama2/docs/tutorials/examples.md index 46c2f847..6c33438d 100644 --- a/docs/Lama2/docs/tutorials/examples.md +++ b/docs/Lama2/docs/tutorials/examples.md @@ -69,8 +69,18 @@ Get [Source File](https://github.com/HexmosTech/Lama2/tree/main/examples/0003_co ## Environment Variables: Switch base URL -Specify variables in `l2.env` and then load -them up in the API files. Presently, **the `l2.env` file should reside in the same directory as the `.l2` API file.** +Specify global variables in `l2config.env` in parent directory. +**The global variables of `l2config.env` will be overwritten by local `l2.env` variables.** + +Specify variables in `l2.env` and then load them up in the API files. +Presently, **the `l2.env` file should reside in the same directory as the `.l2` API file.** + +**l2config.env** + +``` +export LOCAL="http://localhost:8001" +export REMOTE="http://httpbin.in" +``` **l2.env** From 655a236da4d94f7b51fd03c8d6ee21725bc5776e Mon Sep 17 00:00:00 2001 From: lovestaco Date: Wed, 12 Jul 2023 09:28:45 +0530 Subject: [PATCH 05/23] examples.md --- docs/Lama2/docs/tutorials/examples.md | 37 +++++++++--------- docs/Lama2/docs/tutorials/image.png | Bin 0 -> 16733 bytes .../0019_env_switch_project_root.l2 | 6 +++ .../0019_env_switch_project_root/l2config.env | 2 + .../0020_override_project_root_local.l2 | 6 +++ .../0020_override_project_root_local/l2.env | 1 + .../l2config.env | 1 + 7 files changed, 35 insertions(+), 18 deletions(-) create mode 100644 docs/Lama2/docs/tutorials/image.png create mode 100644 examples/0019_env_switch_project_root/0019_env_switch_project_root/0019_env_switch_project_root.l2 create mode 100644 examples/0019_env_switch_project_root/l2config.env create mode 100644 examples/0020_override_project_root_local/0020_override_project_root_local/0020_override_project_root_local.l2 create mode 100644 examples/0020_override_project_root_local/0020_override_project_root_local/l2.env create mode 100644 examples/0020_override_project_root_local/l2config.env diff --git a/docs/Lama2/docs/tutorials/examples.md b/docs/Lama2/docs/tutorials/examples.md index 6c33438d..018da49c 100644 --- a/docs/Lama2/docs/tutorials/examples.md +++ b/docs/Lama2/docs/tutorials/examples.md @@ -69,37 +69,38 @@ Get [Source File](https://github.com/HexmosTech/Lama2/tree/main/examples/0003_co ## Environment Variables: Switch base URL -Specify global variables in `l2config.env` in parent directory. -**The global variables of `l2config.env` will be overwritten by local `l2.env` variables.** -Specify variables in `l2.env` and then load them up in the API files. -Presently, **the `l2.env` file should reside in the same directory as the `.l2` API file.** - -**l2config.env** +### 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 + +**l2.env** ``` -export LOCAL="http://localhost:8001" -export REMOTE="http://httpbin.in" +export LOCAL="http://localhost:8000" +export REMOTE="http://httpbin.org" ``` +Get [Source Files](https://github.com/HexmosTech/Lama2/tree/main/examples/0004_env_switch_root) -**l2.env** +### 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`: + +Within such a structure, you can have an API file anywhere, which can use variables defined in the project-level variables: +**l2config.env** ``` export LOCAL="http://localhost:8000" export REMOTE="http://httpbin.org" ``` +Get [Source Files](https://github.com/HexmosTech/Lama2/tree/main/examples/0019_env_switch_global_root) -**env_example.l2** -``` -POST -${REMOTE}/post +### Case 3: Override Project-level variable with local variable -{ - "lorem": "ipsum" -} -``` +![Example of override of l2config.env variable with l2.env](image.png) + +Get [Source Files](https://github.com/HexmosTech/Lama2/tree/main/examples/0020_override_project_root_local) -Get [Source Files](https://github.com/HexmosTech/Lama2/tree/main/examples/0004_env_switch_root) ## Headers diff --git a/docs/Lama2/docs/tutorials/image.png b/docs/Lama2/docs/tutorials/image.png new file mode 100644 index 0000000000000000000000000000000000000000..df8b877fed601503e476af8cea96e9f338f4b81a GIT binary patch literal 16733 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 literal 0 HcmV?d00001 diff --git a/examples/0019_env_switch_project_root/0019_env_switch_project_root/0019_env_switch_project_root.l2 b/examples/0019_env_switch_project_root/0019_env_switch_project_root/0019_env_switch_project_root.l2 new file mode 100644 index 00000000..11264122 --- /dev/null +++ b/examples/0019_env_switch_project_root/0019_env_switch_project_root/0019_env_switch_project_root.l2 @@ -0,0 +1,6 @@ +POST +${REMOTE}/post + +{ + "lorem": "ipsum" +} \ No newline at end of file diff --git a/examples/0019_env_switch_project_root/l2config.env b/examples/0019_env_switch_project_root/l2config.env new file mode 100644 index 00000000..4e72e78f --- /dev/null +++ b/examples/0019_env_switch_project_root/l2config.env @@ -0,0 +1,2 @@ +export LOCAL="http://localhost:8000" +export REMOTE="http://httpbin.org" \ No newline at end of file diff --git a/examples/0020_override_project_root_local/0020_override_project_root_local/0020_override_project_root_local.l2 b/examples/0020_override_project_root_local/0020_override_project_root_local/0020_override_project_root_local.l2 new file mode 100644 index 00000000..11264122 --- /dev/null +++ b/examples/0020_override_project_root_local/0020_override_project_root_local/0020_override_project_root_local.l2 @@ -0,0 +1,6 @@ +POST +${REMOTE}/post + +{ + "lorem": "ipsum" +} \ No newline at end of file diff --git a/examples/0020_override_project_root_local/0020_override_project_root_local/l2.env b/examples/0020_override_project_root_local/0020_override_project_root_local/l2.env new file mode 100644 index 00000000..d75a291d --- /dev/null +++ b/examples/0020_override_project_root_local/0020_override_project_root_local/l2.env @@ -0,0 +1 @@ +export REMOTE="http://httpbin.org/dev" diff --git a/examples/0020_override_project_root_local/l2config.env b/examples/0020_override_project_root_local/l2config.env new file mode 100644 index 00000000..000e4958 --- /dev/null +++ b/examples/0020_override_project_root_local/l2config.env @@ -0,0 +1 @@ +export REMOTE="http://httpbin.org/prod" \ No newline at end of file From 548e43e1bb3bca390be7b2abcbaa5374d2fdb167 Mon Sep 17 00:00:00 2001 From: lovestaco Date: Wed, 12 Jul 2023 16:37:19 +0530 Subject: [PATCH 06/23] Updating preprocess, documentation --- docs/Lama2/docs/reference/preprocess.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/Lama2/docs/reference/preprocess.md b/docs/Lama2/docs/reference/preprocess.md index 6e04c18d..35ab60af 100644 --- a/docs/Lama2/docs/reference/preprocess.md +++ b/docs/Lama2/docs/reference/preprocess.md @@ -67,7 +67,9 @@ 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 \`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. +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 from the project directory. + + Then loads the \`l2.env\` local variables file from the present directory, Variables which are already declared in \`l2config.env\` will be overwritten with local variable of \`l2.env\`. Once done, it reverts back to the original directory, and returns the processed l2 file. ## func [LoadElfEnv]() From 48f315463ff4011d5ebc4eb29460943aafa3a828 Mon Sep 17 00:00:00 2001 From: lovestaco Date: Wed, 12 Jul 2023 16:43:52 +0530 Subject: [PATCH 07/23] Updating architecture, documentation --- docs/Lama2/docs/reference/architecture.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/Lama2/docs/reference/architecture.md b/docs/Lama2/docs/reference/architecture.md index 83035e8f..e4d9dc8a 100644 --- a/docs/Lama2/docs/reference/architecture.md +++ b/docs/Lama2/docs/reference/architecture.md @@ -48,7 +48,8 @@ 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 `l2config.env` and `l2.env` + 2. If (1) fails, try fetch Local env variable from `l2.env` + 3. Try fetch Project env variable from `l2config.env` 2. Use the processed elements to create an httpie-go request 3. Fetch response 5. If necessary, write the last transaction to `.json` file \ No newline at end of file From d12b69b07026d4b3e4a40cdd29d30f6bee49d738 Mon Sep 17 00:00:00 2001 From: lovestaco Date: Wed, 12 Jul 2023 16:58:52 +0530 Subject: [PATCH 08/23] Updating l2format, documentation --- docs/Lama2/docs/explanation/l2format.md | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/docs/Lama2/docs/explanation/l2format.md b/docs/Lama2/docs/explanation/l2format.md index 41da8e6b..d63820c8 100644 --- a/docs/Lama2/docs/explanation/l2format.md +++ b/docs/Lama2/docs/explanation/l2format.md @@ -83,25 +83,25 @@ 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/` +### API environment variables can be defined locally in `l2.env` -The *l2* loads up variables from `l2config.env` and then `l2.env`. -If same variable is found in `l2.env` then overwrites the global variable. -Example `l2config.env`: +By default, *l2* looks for a `l2.env` file in the same directory as the given +request file directory. Example `l2.env`: ``` -export PHOTO=`base64 aadhaarsmall.jpg` -export AHOST="http://localhost:8001" +export PHOTO=`base64 aadhaarlarge.jpg` +export AHOST="http://localhost:8000" ``` -### Environments variables/commands can be defined in `/l2.env` +### API environment variables can be defined at project level using `l2config.env` -By default, *l2* looks for a `l2.env` file in the same directory as the given -request file directory. Example `l2.env`: +*l2* loads local variables from `l2.env`. +If not found then uses variables from `l2config.env`. +Example `l2config.env`: ``` -export PHOTO=`base64 aadhaarlarge.jpg` -export AHOST="http://localhost:8000" +export PHOTO=`base64 aadhaarsmall.jpg` +export AHOST="http://localhost:8001" ``` #### The environment file can load results of commands From 549affb75acf037791ee56f20dcec8d11a72b8e5 Mon Sep 17 00:00:00 2001 From: lovestaco Date: Sun, 16 Jul 2023 15:04:35 +0530 Subject: [PATCH 09/23] Adding command to get JSON of envs - 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. --- controller/controller.go | 11 +++ docs/Lama2/docs/reference/preprocess.md | 47 ++++++------- lama2cmd/lama2cmd.go | 1 + preprocess/preprocess.go | 93 +++++++++++++++++++------ tests/base64_test.go | 2 +- 5 files changed, 108 insertions(+), 46 deletions(-) diff --git a/controller/controller.go b/controller/controller.go index 297e03ca..9f81145d 100644 --- a/controller/controller.go +++ b/controller/controller.go @@ -87,6 +87,17 @@ func Process(version string) { _, dir, _ := utils.GetFilePathComponents(o.Positional.LamaAPIFile) oldDir, _ := os.Getwd() utils.ChangeWorkingDir(dir) + + if o.Env { + jsonEnvs,err := preprocess.GetL2EnvVariables(dir) + if err != nil { + log.Error().Str("Type", "Preprocess").Msg(err.Error()) + return + } + log.Info().Str("Type", "Preprocess").Msg("Env Variables:\n" + string(jsonEnvs)) + return + } + preprocess.LoadEnvironments(dir) utils.ChangeWorkingDir(oldDir) p := parser.NewLama2Parser() diff --git a/docs/Lama2/docs/reference/preprocess.md b/docs/Lama2/docs/reference/preprocess.md index 35ab60af..7bb39203 100644 --- a/docs/Lama2/docs/reference/preprocess.md +++ b/docs/Lama2/docs/reference/preprocess.md @@ -10,18 +10,17 @@ Package preprocess provides facilities to expand environment variables in \`.l2\ ## Index -- [func Expand(s string, vm *goja.Runtime, mapping map[string]string) string](<#func-expand>) -- [func ExpandEnv(s string, vm *goja.Runtime) string](<#func-expandenv>) -- [func ExpandHeaders(block *gabs.Container, vm *goja.Runtime)](<#func-expandheaders>) -- [func ExpandJSON(block *gabs.Container, vm *goja.Runtime)](<#func-expandjson>) -- [func ExpandURL(block *gabs.Container, vm *goja.Runtime)](<#func-expandurl>) -- [func GetLamaFileAsString(path string) string](<#func-getlamafileasstring>) -- [func LamaFile(inputFile string) (string, string)](<#func-lamafile>) -- [func LoadElfEnv(l2path string)](<#func-loadelfenv>) -- [func ProcessVarsInBlock(block *gabs.Container, vm *goja.Runtime)](<#func-processvarsinblock>) - - -## func [Expand]() +- [func Expand(s string, vm \*goja.Runtime, mapping map[string]string) string](#func-expand) +- [func ExpandEnv(s string, vm \*goja.Runtime) string](#func-expandenv) +- [func ExpandHeaders(block *gabs.Container, vm *goja.Runtime)](#func-expandheaders) +- [func ExpandJSON(block *gabs.Container, vm *goja.Runtime)](#func-expandjson) +- [func ExpandURL(block *gabs.Container, vm *goja.Runtime)](#func-expandurl) +- [func GetLamaFileAsString(path string) string](#func-getlamafileasstring) +- [func LamaFile(inputFile string) (string, string)](#func-lamafile) +- [func LoadEnvFile(l2path string)](#func-loadenvfile) +- [func ProcessVarsInBlock(block *gabs.Container, vm *goja.Runtime)](#func-processvarsinblock) + +## func [Expand](https://github.com/HexmosTech/Lama2/blob/master/preprocess/expandvar.go#L19) ```go func Expand(s string, vm *goja.Runtime, mapping map[string]string) string @@ -29,7 +28,7 @@ func Expand(s string, vm *goja.Runtime, mapping map[string]string) string Expand replaces $\{var\} or $var in the string based on the mapping function. For example, os.ExpandEnv\(s\) is equivalent to os.Expand\(s, os.Getenv\). -## func [ExpandEnv]() +## func [ExpandEnv](https://github.com/HexmosTech/Lama2/blob/master/preprocess/expandvar.go#L74) ```go func ExpandEnv(s string, vm *goja.Runtime) string @@ -37,31 +36,31 @@ func ExpandEnv(s string, vm *goja.Runtime) string ExpandEnv replaces $\{var\} or $var in the string according to the values of the current environment variables. References to undefined variables are replaced by the empty string. -## func [ExpandHeaders]() +## func [ExpandHeaders](https://github.com/HexmosTech/Lama2/blob/master/preprocess/preprocess.go#L25) ```go func ExpandHeaders(block *gabs.Container, vm *goja.Runtime) ``` -## func [ExpandJSON]() +## func [ExpandJSON](https://github.com/HexmosTech/Lama2/blob/master/preprocess/preprocess.go#L77) ```go func ExpandJSON(block *gabs.Container, vm *goja.Runtime) ``` -## func [ExpandURL]() +## func [ExpandURL](https://github.com/HexmosTech/Lama2/blob/master/preprocess/preprocess.go#L45) ```go func ExpandURL(block *gabs.Container, vm *goja.Runtime) ``` -## func [GetLamaFileAsString]() +## func [GetLamaFileAsString](https://github.com/HexmosTech/Lama2/blob/master/preprocess/preprocess.go#L104) ```go func GetLamaFileAsString(path string) string ``` -## func [LamaFile]() +## func [LamaFile](https://github.com/HexmosTech/Lama2/blob/master/preprocess/preprocess.go#L118) ```go func LamaFile(inputFile string) (string, string) @@ -69,20 +68,18 @@ 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 \`l2config.env\` global variables file from the project directory. - Then loads the \`l2.env\` local variables file from the present directory, Variables which are already declared in \`l2config.env\` will be overwritten with local variable of \`l2.env\`. Once done, it reverts back to the original directory, and returns the processed l2 file. +Then loads the \`l2.env\` local variables file from the present directory, Variables which are already declared in \`l2config.env\` will be overwritten with local variable of \`l2.env\`. Once done, it reverts back to the original directory, and returns the processed l2 file. -## func [LoadElfEnv]() +## func [LoadEnvFile](https://github.com/HexmosTech/Lama2/blob/master/preprocess/preprocess.go#L97) ```go -func LoadElfEnv(l2path string) +func LoadEnvFile(l2path string) ``` -## func [ProcessVarsInBlock]() +## func [ProcessVarsInBlock](https://github.com/HexmosTech/Lama2/blob/master/preprocess/preprocess.go#L19) ```go func ProcessVarsInBlock(block *gabs.Container, vm *goja.Runtime) ``` - - -Generated by [gomarkdoc]() +Generated by [gomarkdoc](https://github.com/princjef/gomarkdoc) diff --git a/lama2cmd/lama2cmd.go b/lama2cmd/lama2cmd.go index 664a1eb1..79d4260f 100644 --- a/lama2cmd/lama2cmd.go +++ b/lama2cmd/lama2cmd.go @@ -26,6 +26,7 @@ type Opts struct { PostmanFile string `short:"p" long:"postmanfile" description:"JSON export from Postman (Settings -> Data -> Export Data)"` LamaDir string `short:"l" long:"lama2dir" description:"Output directory to put .l2 files after conversion from Postman format"` Help bool `short:"h" long:"help" group:"AddHelp" description:"Usage help for Lama2"` + Env bool `short:"e" long:"env" description:"Get a JSON of environment variables"` Version bool `long:"version" description:"Print Lama2 binary version"` Positional struct { diff --git a/preprocess/preprocess.go b/preprocess/preprocess.go index e1f091f5..24828993 100644 --- a/preprocess/preprocess.go +++ b/preprocess/preprocess.go @@ -5,6 +5,7 @@ package preprocess import ( "encoding/json" + "errors" "fmt" "io/ioutil" "os" @@ -98,33 +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) + for parentDir != string(filepath.Separator) { + l2ConfigPath := filepath.Join(parentDir, "l2config.env") + _, err := os.Stat(l2ConfigPath) + if err == nil { + return l2ConfigPath, nil // Found the l2config.env file + } + parentDir = filepath.Dir(parentDir) + } + return "", errors.New("Didn't find l2config.env in the API directory") +} + +func LoadEnvFile(l2path string) { + envFileName := filepath.Base(l2path) err := godotenv.Load(l2path) if err != nil { - log.Info().Str("Type", "Preprocess").Msg("Didn't find l2.env in the API directory") + log.Info().Str("Type", "Preprocess").Msg("Didn't find "+ envFileName +" in the API directory") } } -func LoadConfigEnv(l2ConfigPath string) { - err := godotenv.Load(l2ConfigPath) - if err != nil { - parentDir := filepath.Dir(l2ConfigPath) - for parentDir != string(filepath.Separator) { - l2ConfigPath = filepath.Join(parentDir, "l2config.env") - err = godotenv.Load(l2ConfigPath) - if err == nil { - log.Info().Str("Type", "Preprocess").Str("l2config.env found in", parentDir).Msg("") - return // Found the l2config.env file, exit the function - } - parentDir = filepath.Dir(parentDir) - } - log.Error().Str("Type", "Preprocess").Msg("Didn't find l2config.env in the API directory") +func LoadEnvironments(dir string) { + l2ConfigPath, err := SearchL2ConfigEnv(dir) + if err != nil { + log.Info().Str("Type", "Preprocess").Msg(err.Error()) + } else { + LoadEnvFile(l2ConfigPath) // Loads global variables from l2config.env } + LoadEnvFile(path.Join(dir, "l2.env")) // Overwrites the global variables if declared again in l2.env } -func LoadEnvironments(dir string) { - LoadConfigEnv(path.Join(dir, "l2config.env")) // Loads global variables from l2config.env - LoadElfEnv(path.Join(dir, "l2.env")) // Overwrites the global variables if declared again in l2.env +func readFile(filename string) (envMap map[string]string, err error) { + file, err := os.Open(filename) + if err != nil { + return + } + defer file.Close() + return godotenv.Parse(file) +} + +func populateEnvMap(envMap map[string]map[string]interface{}, envPath string, source string) error { + envs, err := readFile(envPath) + if err != nil { + return err + } + for key, value := range envs { + variable := make(map[string]interface{}) + variable["val"] = value + variable["src"] = source + envMap[key] = variable + } + return nil +} + +func GetL2EnvVariables(dir string) ([]byte, error) { + finalEnvMap := make(map[string]map[string]interface{}) + + 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()) + } + } + + l2EnvPath := path.Join(dir, "l2.env") + err = populateEnvMap(finalEnvMap, l2EnvPath, "l2env") + if err != nil { + log.Error().Str("Type", "Preprocess").Msg(err.Error()) + } + + 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 jsonEnvs, nil } func GetLamaFileAsString(path string) string { @@ -147,7 +200,7 @@ func LamaFile(inputFile string) (string, string) { oldDir, _ := os.Getwd() utils.ChangeWorkingDir(dir) - LoadElfEnv("l2.env") + LoadEnvFile("l2.env") content = os.ExpandEnv(content) utils.ChangeWorkingDir(oldDir) diff --git a/tests/base64_test.go b/tests/base64_test.go index 0c1d915c..ed00e697 100644 --- a/tests/base64_test.go +++ b/tests/base64_test.go @@ -21,7 +21,7 @@ func TestBase64(t *testing.T) { _, dir, _ := utils.GetFilePathComponents(l2Path) nowPwd, _ := os.Getwd() utils.ChangeWorkingDir(dir) - preprocess.LoadElfEnv(path.Join(dir, "l2.env")) + preprocess.LoadEnvFile(path.Join(dir, "l2.env")) p := parser.NewLama2Parser() parsedAPI, _ := p.Parse(string(apiContent)) fmt.Println(parsedAPI) From a66383b5064ef2d5c456ce27a9276e89acaccc51 Mon Sep 17 00:00:00 2001 From: lovestaco Date: Sun, 16 Jul 2023 19:10:40 +0530 Subject: [PATCH 10/23] Updating l2format and examples, documentation --- docs/Lama2/docs/explanation/l2format.md | 29 +++++++++------- docs/Lama2/docs/tutorials/examples.md | 44 +++++++++++++------------ 2 files changed, 41 insertions(+), 32 deletions(-) diff --git a/docs/Lama2/docs/explanation/l2format.md b/docs/Lama2/docs/explanation/l2format.md index d63820c8..0a0779dd 100644 --- a/docs/Lama2/docs/explanation/l2format.md +++ b/docs/Lama2/docs/explanation/l2format.md @@ -3,12 +3,12 @@ the rules for authoring `.l2` API files. This document expects some familiarity with *Lama2*. To quickly get started with *Lama2*, head over -to [Examples](../tutorials/examples.md). +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 `#` @@ -21,7 +21,6 @@ Fully supported: `GET|HEAD|POST|PUT|DELETE|CONNECT|OPTIONS|TRACE|PATCH` ### JSON is the default submission type, but MULTIPART is supported too - #### `varjson` is a simpler syntax to specify flat JSONs `varjson` values are defined as follows: @@ -42,10 +41,10 @@ The above results in a JSON submission of the form: #### Nested JSON can simply be dumped at the end of the document -The JSON recognition engine is quite lenient. It can deal with +The JSON recognition engine is quite lenient. It can deal with minor errors in the format (such as having single quotes instead of double quotes, trailing garbage, or an extra comma after the -last element in an array,). +last element in an array,). ``` POST @@ -57,8 +56,6 @@ https://httpbin.org/post } ``` - - #### MULTIPART allows both file uploads & the usual fields Example: @@ -75,7 +72,7 @@ file@./helloworld.jpg The *file path is relative to the request file.* -### Cookies are sent as headers +### Cookies are sent as headers Cookies are specified in a `Cookie` header as follows: @@ -93,9 +90,11 @@ export PHOTO=`base64 aadhaarlarge.jpg` 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`. +_l2_ loads local variables from `l2.env`. If not found then uses variables from `l2config.env`. Example `l2config.env`: @@ -104,6 +103,14 @@ export PHOTO=`base64 aadhaarsmall.jpg` 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 + +The local variable's value is taken into consideration + +Get [Source Files](https://github.com/HexmosTech/Lama2/tree/main/examples/0020_override_project_root_local) + #### The environment file can load results of commands Use the backtick notation `\`command\`` to place the results of @@ -117,7 +124,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: @@ -137,4 +144,4 @@ variable `result` contains the response from previous stages. For example, in the above case, `Javascript 2` can access the response from `L2 Request 1` through the `result` variable. -Learn more about request chaining in [Examples](../tutorials/examples.md#chain-requests-using-javascript). \ No newline at end of file +Learn more about request chaining in [Examples](../tutorials/examples.md#chain-requests-using-javascript). diff --git a/docs/Lama2/docs/tutorials/examples.md b/docs/Lama2/docs/tutorials/examples.md index 018da49c..c399936e 100644 --- a/docs/Lama2/docs/tutorials/examples.md +++ b/docs/Lama2/docs/tutorials/examples.md @@ -18,6 +18,7 @@ requests from there. GET https://httpbin.org/get ``` + Get [Source File](https://github.com/HexmosTech/Lama2/tree/main/examples/0000_sample_get.l2) ## JSON POST request @@ -33,6 +34,7 @@ https://httpbin.org/post "c": "d" } ``` + Get [Source File](https://github.com/HexmosTech/Lama2/tree/main/examples/0002_sample_post.l2) ## JSON POST in VarJSON format @@ -48,6 +50,7 @@ https://httpbin.org/post a=b c=d ``` + Get [Source File](https://github.com/HexmosTech/Lama2/tree/main/examples/0001_sample_post_varjson.l2) ## Comments @@ -65,43 +68,40 @@ c=d # Comments work even after the payload ``` + Get [Source File](https://github.com/HexmosTech/Lama2/tree/main/examples/0003_comment.l2) ## Environment Variables: Switch base URL - ### 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. +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 - + **l2.env** + ``` export LOCAL="http://localhost:8000" export REMOTE="http://httpbin.org" ``` -Get [Source Files](https://github.com/HexmosTech/Lama2/tree/main/examples/0004_env_switch_root) ### Case 2: Project-level variables -In Lama2, you can have a large number of API files stored in a hierarchical folder configuration. +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`: - + Within such a structure, you can have an API file anywhere, which can use variables defined in the project-level variables: **l2config.env** + ``` export LOCAL="http://localhost:8000" export REMOTE="http://httpbin.org" ``` -Get [Source Files](https://github.com/HexmosTech/Lama2/tree/main/examples/0019_env_switch_global_root) ### Case 3: Override Project-level variable with local variable ![Example of override of l2config.env variable with l2.env](image.png) -Get [Source Files](https://github.com/HexmosTech/Lama2/tree/main/examples/0020_override_project_root_local) - - ## Headers Use `key:value` format to specify headers. @@ -113,7 +113,7 @@ Specify strings for key/value in three ways: 1. Unquoted (`hello`) ``` -POST +POST https://httpbin.org/post # HEADERS @@ -130,8 +130,9 @@ Get [Source File](https://github.com/HexmosTech/Lama2/tree/main/examples/0005_he !!! Note The data section may appear *before* headers as well (see below) + ``` -POST +POST https://httpbin.org/post @@ -144,13 +145,13 @@ X-Parse-Application-Id:'helloworld' X-Parse-REST-API-Key:"byeworld" ``` - ## Send cookies in header Headers represent cookies in *Lama2*. Just specify cookie key value pairs separated by `=` within the header value as shown. + ``` -POST +POST https://httpbin.org/post # HEADERS @@ -159,6 +160,7 @@ Cookie:"sessionid=foo;another-cookie=bar" # DATA hello=world ``` + Get [Source File](https://github.com/HexmosTech/Lama2/tree/main/examples/0006_cookies.l2) ## Fill forms & attach files with MULTIPART @@ -166,7 +168,7 @@ Get [Source File](https://github.com/HexmosTech/Lama2/tree/main/examples/0006_co Use the `MULTIPART` keyword after the HTTP verb to enable forms and file attachments. -The data section may contain any number of +The data section may contain any number of form inputs using the `key=value` syntax. Following the data section, one can specify @@ -178,7 +180,7 @@ POST MULTIPART http://httpbin.org/post -'X-Parse-Application-Id':hello +'X-Parse-Application-Id':hello X-Parse-REST-API-Key:"world" # DATA @@ -187,11 +189,12 @@ first=second # FILES myfile@./image.jpeg ``` + Get [Source Files](https://github.com/HexmosTech/Lama2/tree/main/examples/0007_multipart_file) ## Image as Base64 encoded JSON field -We can embed images (or other files) as +We can embed images (or other files) as base64 strings in JSON using *Lama2*. First, we define a `PHOTO` variable, loaded @@ -205,8 +208,7 @@ export PHOTO=`base64 -w 0 image.jpeg` Next, we refer to the `PHOTO` variable in the API file. Pay special attention to the -quoting mechanism `"'{PHOTO}'"`. - +quoting mechanism `"'{PHOTO}'"`. !!! warning @@ -224,6 +226,7 @@ http://httpbin.org/post "imageb64_field": "'${PHOTO}'", } ``` + Get [Source Files](https://github.com/HexmosTech/Lama2/tree/main/examples/0008_base64_image) ## Chain requests using Javascript @@ -271,5 +274,4 @@ Authorization: 'Bearer ${TOKEN}' {} ``` - -Get [Source Files](https://github.com/HexmosTech/Lama2/tree/main/examples/0009_processor_basic) \ No newline at end of file +Get [Source Files](https://github.com/HexmosTech/Lama2/tree/main/examples/0009_processor_basic) From be15f49f8b820b8fac983803a12b4089f2cabe5d Mon Sep 17 00:00:00 2001 From: lovestaco Date: Mon, 17 Jul 2023 20:27:42 +0530 Subject: [PATCH 11/23] Search l2configenv from the l2file level --- preprocess/preprocess.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/preprocess/preprocess.go b/preprocess/preprocess.go index 24828993..5063ce2e 100644 --- a/preprocess/preprocess.go +++ b/preprocess/preprocess.go @@ -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) From a1b1b339139753673baf441ac58abf1af2a6ebbd Mon Sep 17 00:00:00 2001 From: lovestaco Date: Tue, 18 Jul 2023 10:33:57 +0530 Subject: [PATCH 12/23] Pure functions for GetL2EnvVariables Removing populateFinalENv() Adding getEnvMap() --- controller/controller.go | 4 ++-- preprocess/preprocess.go | 48 +++++++++++++++++++++++++++++++--------- 2 files changed, 39 insertions(+), 13 deletions(-) diff --git a/controller/controller.go b/controller/controller.go index 9f81145d..18a16d11 100644 --- a/controller/controller.go +++ b/controller/controller.go @@ -68,7 +68,6 @@ func HandleParsedFile(parsedAPI *gabs.Container, o *lama2cmd.Opts, dir string) { if o.Output != "" { outputmanager.WriteJSONOutput(resp, o.Output) } - } // Process initiates the following tasks in the given order: @@ -94,7 +93,8 @@ func Process(version string) { log.Error().Str("Type", "Preprocess").Msg(err.Error()) return } - log.Info().Str("Type", "Preprocess").Msg("Env Variables:\n" + string(jsonEnvs)) + // Frontend can read the stdout for this command and get the JSON of all the env's + fmt.Println(string(jsonEnvs)) return } diff --git a/preprocess/preprocess.go b/preprocess/preprocess.go index 5063ce2e..e3e75197 100644 --- a/preprocess/preprocess.go +++ b/preprocess/preprocess.go @@ -153,30 +153,55 @@ 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{} { 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 } @@ -188,6 +213,7 @@ func GetLamaFileAsString(path string) string { return string(b) } + // 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, From caece118f443a9e152d81afd069a0ddd2538e6b2 Mon Sep 17 00:00:00 2001 From: lovestaco Date: Tue, 18 Jul 2023 10:34:45 +0530 Subject: [PATCH 13/23] Updating documentation l2format.md architecture.md preperocess.md examples.md --- docs/Lama2/docs/explanation/l2format.md | 23 +++++++++++++---------- docs/Lama2/docs/reference/architecture.md | 2 +- docs/Lama2/docs/reference/preprocess.md | 2 +- docs/Lama2/docs/tutorials/examples.md | 14 +++++++------- 4 files changed, 22 insertions(+), 19 deletions(-) diff --git a/docs/Lama2/docs/explanation/l2format.md b/docs/Lama2/docs/explanation/l2format.md index 0a0779dd..f4a2d5b5 100644 --- a/docs/Lama2/docs/explanation/l2format.md +++ b/docs/Lama2/docs/explanation/l2format.md @@ -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 `#` @@ -82,8 +82,9 @@ Cookie:'sessionid=foo;another-cookie=bar' ### 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 +93,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`: ``` @@ -105,12 +105,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 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 +127,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: diff --git a/docs/Lama2/docs/reference/architecture.md b/docs/Lama2/docs/reference/architecture.md index e4d9dc8a..d04a042e 100644 --- a/docs/Lama2/docs/reference/architecture.md +++ b/docs/Lama2/docs/reference/architecture.md @@ -49,7 +49,7 @@ From a high level, how does it work now? 1. Replace variables with values in the following order 1. Try fetch variable from Javascript VM 2. If (1) fails, try fetch Local env variable from `l2.env` - 3. Try fetch Project env variable from `l2config.env` + 3. Try fetch root env variable from `l2config.env` 2. Use the processed elements to create an httpie-go request 3. Fetch response 5. If necessary, write the last transaction to `.json` file \ No newline at end of file diff --git a/docs/Lama2/docs/reference/preprocess.md b/docs/Lama2/docs/reference/preprocess.md index 7bb39203..050880bd 100644 --- a/docs/Lama2/docs/reference/preprocess.md +++ b/docs/Lama2/docs/reference/preprocess.md @@ -66,7 +66,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 \`l2config.env\` global variables file from the project directory. +LamaFile takes in a path to an API file. It moves into the API file directory, reads the API contents, loads the \`l2config.env\` root variable file from the project directory. Then loads the \`l2.env\` local variables file from the present directory, Variables which are already declared in \`l2config.env\` will be overwritten with local variable of \`l2.env\`. Once done, it reverts back to the original directory, and returns the processed l2 file. diff --git a/docs/Lama2/docs/tutorials/examples.md b/docs/Lama2/docs/tutorials/examples.md index c399936e..a9029fde 100644 --- a/docs/Lama2/docs/tutorials/examples.md +++ b/docs/Lama2/docs/tutorials/examples.md @@ -41,7 +41,7 @@ Get [Source File](https://github.com/HexmosTech/Lama2/tree/main/examples/0002_sa Make a POST request with JSON body specified as `key=value`. *Lama2* converts the input into -a corresponding JSON value `{"a": "b", "c": "d"}`. We call the `key=value` format *VarJSON*. This example produces an effect identical to the [previous one](#basic-json-post) +a corresponding JSON value `{"a": "b", "c": "d"}`. We call the `key=value` format _VarJSON_. This example produces an effect identical to the [previous one](#basic-json-post) ``` POST @@ -85,12 +85,12 @@ export LOCAL="http://localhost:8000" export REMOTE="http://httpbin.org" ``` -### Case 2: Project-level variables +### Case 2: Root 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`: -Within such a structure, you can have an API file anywhere, which can use variables defined in the project-level variables: +Within such a structure, you can have an API file anywhere, which can use variables defined in the root variables: **l2config.env** ``` @@ -98,9 +98,9 @@ export LOCAL="http://localhost:8000" export REMOTE="http://httpbin.org" ``` -### Case 3: Override Project-level variable with local variable +### Case 3: Override Root variable with local variable -![Example of override of l2config.env variable with l2.env](image.png) +![Override of l2config.env with l2.env variable](image.png) ## Headers @@ -147,7 +147,7 @@ X-Parse-REST-API-Key:"byeworld" ## Send cookies in header -Headers represent cookies in *Lama2*. Just specify cookie key value pairs separated by +Headers represent cookies in _Lama2_. Just specify cookie key value pairs separated by `=` within the header value as shown. ``` @@ -195,7 +195,7 @@ Get [Source Files](https://github.com/HexmosTech/Lama2/tree/main/examples/0007_m ## Image as Base64 encoded JSON field We can embed images (or other files) as -base64 strings in JSON using *Lama2*. +base64 strings in JSON using _Lama2_. First, we define a `PHOTO` variable, loaded up with the results of the `base64` command. From 36d2d4f213ec3f37970688a8fd3f693982114e6d Mon Sep 17 00:00:00 2001 From: lovestaco Date: Tue, 18 Jul 2023 21:11:37 +0530 Subject: [PATCH 14/23] Make lint and gofumpt, lint errors --- codegen/codegen.go | 7 ++----- controller/controller.go | 4 ++-- lama2cmd/lama2cmd.go | 3 +-- parser/jsonparser.go | 2 +- parser/lama2parser.go | 1 - preprocess/expandvar.go | 4 ++-- preprocess/preprocess.go | 4 +--- tests/base64_test.go | 2 -- tests/importer_test.go | 2 +- tests/js_test.go | 2 +- tests/lama2_test.go | 4 ++-- tests/multistage_test.go | 4 ++-- tests/parser_test.go | 6 +++--- tests/preprocess_test.go | 2 +- 14 files changed, 19 insertions(+), 28 deletions(-) diff --git a/codegen/codegen.go b/codegen/codegen.go index decbd402..1982034e 100644 --- a/codegen/codegen.go +++ b/codegen/codegen.go @@ -15,10 +15,8 @@ import ( "github.com/atotto/clipboard" ) -var ( - //go:embed httpsnippet.js - snippetcore string -) +//go:embed httpsnippet.js +var snippetcore string type SnippetArgs struct { Language string @@ -43,7 +41,6 @@ func PrepareHTTPSnippetGenerator(snippetArgs SnippetArgs) string { // takes in the headers in L2 format, and generates // HAR compatible func GetHARHeadersCookies(headers *gabs.Container) (*gabs.Container, *gabs.Container) { - headersData := gabs.New() headersData.Array() diff --git a/controller/controller.go b/controller/controller.go index 18a16d11..3a8111a6 100644 --- a/controller/controller.go +++ b/controller/controller.go @@ -88,14 +88,14 @@ func Process(version string) { utils.ChangeWorkingDir(dir) if o.Env { - jsonEnvs,err := preprocess.GetL2EnvVariables(dir) + jsonEnvs, err := preprocess.GetL2EnvVariables(dir) if err != nil { log.Error().Str("Type", "Preprocess").Msg(err.Error()) return } // Frontend can read the stdout for this command and get the JSON of all the env's fmt.Println(string(jsonEnvs)) - return + return } preprocess.LoadEnvironments(dir) diff --git a/lama2cmd/lama2cmd.go b/lama2cmd/lama2cmd.go index 79d4260f..e264b302 100644 --- a/lama2cmd/lama2cmd.go +++ b/lama2cmd/lama2cmd.go @@ -26,7 +26,7 @@ type Opts struct { PostmanFile string `short:"p" long:"postmanfile" description:"JSON export from Postman (Settings -> Data -> Export Data)"` LamaDir string `short:"l" long:"lama2dir" description:"Output directory to put .l2 files after conversion from Postman format"` Help bool `short:"h" long:"help" group:"AddHelp" description:"Usage help for Lama2"` - Env bool `short:"e" long:"env" description:"Get a JSON of environment variables"` + Env bool `short:"e" long:"env" description:"Get a JSON of environment variables"` Version bool `long:"version" description:"Print Lama2 binary version"` Positional struct { @@ -102,7 +102,6 @@ func ArgParsing(o *Opts, version string) { log.Fatal().Msg("To convert Postman export to Lama2, try: l2 -p PostmanFile -l Lama2Dir") os.Exit(1) } - } // GetAndValidateCmd takes in the user's CLI input, and checks diff --git a/parser/jsonparser.go b/parser/jsonparser.go index 46ee958a..62112b0a 100644 --- a/parser/jsonparser.go +++ b/parser/jsonparser.go @@ -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{} { return source } diff --git a/parser/lama2parser.go b/parser/lama2parser.go index 0abe82ba..665ddec2 100644 --- a/parser/lama2parser.go +++ b/parser/lama2parser.go @@ -38,7 +38,6 @@ func (p *Lama2Parser) Start() (*gabs.Container, error) { } func (p *Lama2Parser) Lama2File() (*gabs.Container, error) { - // Trying to get: // PSBlock? Requestor [SPSBlock Requestor]* diff --git a/preprocess/expandvar.go b/preprocess/expandvar.go index dd4c5cc6..7b821e30 100644 --- a/preprocess/expandvar.go +++ b/preprocess/expandvar.go @@ -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++ { + // } return s[:i], i } diff --git a/preprocess/preprocess.go b/preprocess/preprocess.go index e3e75197..887e2449 100644 --- a/preprocess/preprocess.go +++ b/preprocess/preprocess.go @@ -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") } } @@ -178,7 +178,6 @@ func combineEnvMaps(envMaps ...map[string]map[string]interface{}) map[string]map return finalEnvMap } - func GetL2EnvVariables(dir string) ([]byte, error) { l2ConfigPath, err := SearchL2ConfigEnv(dir) if err != nil { @@ -213,7 +212,6 @@ func GetLamaFileAsString(path string) string { return string(b) } - // 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, diff --git a/tests/base64_test.go b/tests/base64_test.go index ed00e697..764b9297 100644 --- a/tests/base64_test.go +++ b/tests/base64_test.go @@ -14,7 +14,6 @@ import ( ) func TestBase64(t *testing.T) { - // parse file l2Path := "../examples/0008_base64_image/0008_base64_image.l2" apiContent, _ := os.ReadFile(l2Path) @@ -43,5 +42,4 @@ func TestBase64(t *testing.T) { fmt.Println(block) } utils.ChangeWorkingDir(nowPwd) - } diff --git a/tests/importer_test.go b/tests/importer_test.go index d4509a43..38f08443 100644 --- a/tests/importer_test.go +++ b/tests/importer_test.go @@ -9,7 +9,7 @@ import ( "github.com/HexmosTech/lama2/importer" ) -func TestPostman(t *testing.T) { +func TestPostman(_ *testing.T) { path, _ := os.Getwd() fmt.Println(path) pJSON := importer.ReadPostmanFile(filepath.Join(".", "data", "Backup.postman_dump.json")) diff --git a/tests/js_test.go b/tests/js_test.go index adfd61be..16ba966e 100644 --- a/tests/js_test.go +++ b/tests/js_test.go @@ -8,7 +8,7 @@ import ( "github.com/HexmosTech/lama2/cmdexec" ) -func TestRunVMCode(t *testing.T) { +func TestRunVMCode(_ *testing.T) { vm := cmdexec.GetJSVm() cmdexec.RunVMCode("let meaning=42", vm) } diff --git a/tests/lama2_test.go b/tests/lama2_test.go index c324cd49..9da7b359 100644 --- a/tests/lama2_test.go +++ b/tests/lama2_test.go @@ -70,7 +70,7 @@ func PerformParserMatch(text string) (*gabs.Container, error) { return got, e } -func TestValidFiles(t *testing.T) { +func TestValidFiles(_ *testing.T) { matchFiles, _ := getDataFiles("../elfparser/ElfTestSuite", "y_*") // matchFiles, _ := getDataFiles("../elfparser/ElfTestSuite", "y_0009_varjson_basic.l2") // matchFiles, _ := getDataFiles("../elfparser/ElfTestSuite", "y_0012_varjson_multipart.l2") @@ -90,7 +90,7 @@ func TestValidFiles(t *testing.T) { } } -func TestInvalidFiles(t *testing.T) { +func TestInvalidFiles(_ *testing.T) { matchFiles, _ := getDataFiles("../elfparser/ElfTestSuite", "n_*") for _, m := range matchFiles { b, err := os.ReadFile(m) // just pass the file name diff --git a/tests/multistage_test.go b/tests/multistage_test.go index 72810497..a580b459 100644 --- a/tests/multistage_test.go +++ b/tests/multistage_test.go @@ -30,9 +30,9 @@ func TestMultiStageCount(t *testing.T) { for _, block := range parsedAPIblocks { blockType := block.S("type").Data().(string) if blockType == "processor" { - procCount += 1 + procCount ++ } else if blockType == "Lama2File" { - reqCount += 1 + reqCount ++ } } diff --git a/tests/parser_test.go b/tests/parser_test.go index 44caf110..c679b5b8 100644 --- a/tests/parser_test.go +++ b/tests/parser_test.go @@ -9,13 +9,13 @@ import ( "github.com/rs/zerolog/log" ) -func TestLama2Parser(t *testing.T) { +func TestLama2Parser(_ *testing.T) { p := parser.NewLama2Parser() got, _ := p.Parse("GET http://google.com") log.Debug().Str("Received", got.String()).Msg("") } -func TestCharFunc(t *testing.T) { +func TestCharFunc(_ *testing.T) { p := parser.NewLama2Parser() p.SetText("GET http://google.com") @@ -127,7 +127,7 @@ func TestFailMatch(t *testing.T) { // fmt.Println("===") } -func TestLama2Start(t *testing.T) { +func TestLama2Start(_ *testing.T) { p := parser.NewLama2Parser() p.SetText("GET http://google.com") got, _ := p.Start() diff --git a/tests/preprocess_test.go b/tests/preprocess_test.go index 915a22ae..4e024acd 100644 --- a/tests/preprocess_test.go +++ b/tests/preprocess_test.go @@ -7,7 +7,7 @@ import ( "github.com/rs/zerolog/log" ) -func TestPreprocessBasic(t *testing.T) { +func TestPreprocessBasic(_ *testing.T) { op, _ := preprocess.LamaFile("../elfparser/ElfTestSuite/env1/sample.l2") log.Debug().Str("Preprocessed string", op).Msg("") } From ffc95e905baec7e1fdf82c50af6c0ccfda5fe222 Mon Sep 17 00:00:00 2001 From: lovestaco Date: Tue, 18 Jul 2023 21:12:07 +0530 Subject: [PATCH 15/23] Adding varjson variable example, documentation --- docs/Lama2/docs/explanation/l2format.md | 23 ++++++++++++++++++ .../0021_varjson_variable.l2 | 24 +++++++++++++++++++ 2 files changed, 47 insertions(+) create mode 100644 examples/0021_varjson_variable/0021_varjson_variable.l2 diff --git a/docs/Lama2/docs/explanation/l2format.md b/docs/Lama2/docs/explanation/l2format.md index f4a2d5b5..7ed83700 100644 --- a/docs/Lama2/docs/explanation/l2format.md +++ b/docs/Lama2/docs/explanation/l2format.md @@ -80,6 +80,29 @@ 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 = "customer1@gmail.com" + +--- + +POST +${REMOTE}/login +{ + "email": "${EMAIL}", + "password": "customer1@gmail.com" +} +``` + +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` `l2.env` is searched for, from the present directory and variables(local) are loaded from this file. diff --git a/examples/0021_varjson_variable/0021_varjson_variable.l2 b/examples/0021_varjson_variable/0021_varjson_variable.l2 new file mode 100644 index 00000000..4a1ab510 --- /dev/null +++ b/examples/0021_varjson_variable/0021_varjson_variable.l2 @@ -0,0 +1,24 @@ +let REMOTE = "httpbin.org" +let EMAIL = "customer1@gmail.com" + +--- + +POST +${REMOTE}/login +{ + "email": "${EMAIL}", + "password": "customer1@gmail.com" +} + +--- + +let TOKEN = result['jwt'] + +--- + +POST +${REMOTE}/logout +"Authorization": "Bearer ${TOKEN}" +{ + "email": "${EMAIL}", +} \ No newline at end of file From 82690f1a4f3531fcc63d62a9e6f8602e5a0cfada Mon Sep 17 00:00:00 2001 From: lovestaco Date: Wed, 19 Jul 2023 09:49:02 +0530 Subject: [PATCH 16/23] Adding root override and backtick echo var, test - Making changes in the Documentation. --- docs/Lama2/docs/explanation/l2format.md | 2 +- elfparser/ElfTestSuite/echo_get/l2.env | 1 + elfparser/ElfTestSuite/echo_get/y_0019_echo_get.l2 | 2 ++ elfparser/ElfTestSuite/root_variable_override/api/l2.env | 1 + .../root_variable_override/api/y_0020_root_override.l2 | 2 ++ elfparser/ElfTestSuite/root_variable_override/l2config.env | 1 + preprocess/expandvar.go | 2 -- preprocess/preprocess.go | 2 ++ 8 files changed, 10 insertions(+), 3 deletions(-) create mode 100644 elfparser/ElfTestSuite/echo_get/l2.env create mode 100644 elfparser/ElfTestSuite/echo_get/y_0019_echo_get.l2 create mode 100644 elfparser/ElfTestSuite/root_variable_override/api/l2.env create mode 100644 elfparser/ElfTestSuite/root_variable_override/api/y_0020_root_override.l2 create mode 100644 elfparser/ElfTestSuite/root_variable_override/l2config.env diff --git a/docs/Lama2/docs/explanation/l2format.md b/docs/Lama2/docs/explanation/l2format.md index 7ed83700..916d6f1c 100644 --- a/docs/Lama2/docs/explanation/l2format.md +++ b/docs/Lama2/docs/explanation/l2format.md @@ -130,7 +130,7 @@ Get [Source Files](https://github.com/HexmosTech/Lama2/tree/main/examples/0019_e ### If `l2config.env`(root) variables are redeclared in `l2.env`(local) -The local variable's value is taken into consideration regardless of both files reside in same directory +The local variable's value is taken into consideration regardless of both files residing in same directory Get [Source Files](https://github.com/HexmosTech/Lama2/tree/main/examples/0020_override_project_root_local) diff --git a/elfparser/ElfTestSuite/echo_get/l2.env b/elfparser/ElfTestSuite/echo_get/l2.env new file mode 100644 index 00000000..2a9324b2 --- /dev/null +++ b/elfparser/ElfTestSuite/echo_get/l2.env @@ -0,0 +1 @@ +export AHOST=`echo http://httpbin.org` \ No newline at end of file diff --git a/elfparser/ElfTestSuite/echo_get/y_0019_echo_get.l2 b/elfparser/ElfTestSuite/echo_get/y_0019_echo_get.l2 new file mode 100644 index 00000000..eeea2a10 --- /dev/null +++ b/elfparser/ElfTestSuite/echo_get/y_0019_echo_get.l2 @@ -0,0 +1,2 @@ +GET +${AHOST}/get \ No newline at end of file diff --git a/elfparser/ElfTestSuite/root_variable_override/api/l2.env b/elfparser/ElfTestSuite/root_variable_override/api/l2.env new file mode 100644 index 00000000..2a9324b2 --- /dev/null +++ b/elfparser/ElfTestSuite/root_variable_override/api/l2.env @@ -0,0 +1 @@ +export AHOST=`echo http://httpbin.org` \ No newline at end of file diff --git a/elfparser/ElfTestSuite/root_variable_override/api/y_0020_root_override.l2 b/elfparser/ElfTestSuite/root_variable_override/api/y_0020_root_override.l2 new file mode 100644 index 00000000..eeea2a10 --- /dev/null +++ b/elfparser/ElfTestSuite/root_variable_override/api/y_0020_root_override.l2 @@ -0,0 +1,2 @@ +GET +${AHOST}/get \ No newline at end of file diff --git a/elfparser/ElfTestSuite/root_variable_override/l2config.env b/elfparser/ElfTestSuite/root_variable_override/l2config.env new file mode 100644 index 00000000..013c1799 --- /dev/null +++ b/elfparser/ElfTestSuite/root_variable_override/l2config.env @@ -0,0 +1 @@ +export AHOST=`echo NO URL` \ No newline at end of file diff --git a/preprocess/expandvar.go b/preprocess/expandvar.go index 7b821e30..70a638e7 100644 --- a/preprocess/expandvar.go +++ b/preprocess/expandvar.go @@ -114,8 +114,6 @@ func getShellName(s string) (string, int) { } // Scan alphanumerics. var i int - // for i = 0; i < len(s) && isAlphaNum(s[i]); i++ { - // } return s[:i], i } diff --git a/preprocess/preprocess.go b/preprocess/preprocess.go index 887e2449..4f3b0d4c 100644 --- a/preprocess/preprocess.go +++ b/preprocess/preprocess.go @@ -169,6 +169,8 @@ func getEnvMap(envPath string, source string) (map[string]map[string]interface{} } func combineEnvMaps(envMaps ...map[string]map[string]interface{}) map[string]map[string]interface{} { + // First l2config varibales are added to the map. + // Then l2env varibales, so if a variable is redeclared in l2env then it will overwritten and taken to consideration. finalEnvMap := make(map[string]map[string]interface{}) for _, envMap := range envMaps { for key, value := range envMap { From c19afee923a5e79e75ffffb44e703b915b782f64 Mon Sep 17 00:00:00 2001 From: lovestaco Date: Thu, 20 Jul 2023 09:06:58 +0530 Subject: [PATCH 17/23] Adding env_command, test --- .../root_variable_override/l2config.env | 3 +- makefile | 5 +- tests/env_command_test.go | 79 +++++++++++++++++++ 3 files changed, 84 insertions(+), 3 deletions(-) create mode 100644 tests/env_command_test.go diff --git a/elfparser/ElfTestSuite/root_variable_override/l2config.env b/elfparser/ElfTestSuite/root_variable_override/l2config.env index 013c1799..02744d12 100644 --- a/elfparser/ElfTestSuite/root_variable_override/l2config.env +++ b/elfparser/ElfTestSuite/root_variable_override/l2config.env @@ -1 +1,2 @@ -export AHOST=`echo NO URL` \ No newline at end of file +export AHOST=`echo NO URL` +export BHOST="https://httpbin.org" \ No newline at end of file diff --git a/makefile b/makefile index fe1500e6..a32430dc 100644 --- a/makefile +++ b/makefile @@ -23,8 +23,9 @@ gofumpt: gofumpt -w . test: - go test ./tests/ -count=1 - + make buildme + go test ./tests/ -count=1 + benchmark: go test -bench=. -count 1 -run=^# -benchmem ./tests/ diff --git a/tests/env_command_test.go b/tests/env_command_test.go new file mode 100644 index 00000000..8fdbf7e1 --- /dev/null +++ b/tests/env_command_test.go @@ -0,0 +1,79 @@ +package tests + +import ( + // "encoding/json" + "os/exec" + "testing" + "fmt" + "bytes" + "encoding/json" +) + +type EnvData struct { + Src string `json:"src"` + Val string `json:"val"` +} + +func runL2CommandAndParseJSON(t *testing.T, cmdArgs ...string) { + cmd := exec.Command("../build/l2", cmdArgs...) + var stdout bytes.Buffer + cmd.Stdout = &stdout + + // Execute the command + err := cmd.Run() + if err != nil { + // Handle the error if needed + fmt.Printf("Error running l2 command: %v\n", err) + } + + // Retrieve the captured stdout + stdoutOutput := stdout.String() + + fmt.Println(stdoutOutput) + + // Convert the stdoutOutput string to []byte slice + outputBytes := []byte(stdoutOutput) + + envMap := make(map[string]EnvData) + err = json.Unmarshal(outputBytes, &envMap) + if err != nil { + t.Fatalf("Error unmarshaling JSON: %v\nOutput:\n%s", err, stdoutOutput) + } + // Example assertion: Check the "AHOST" key + if ahost, ok := envMap["AHOST"]; !ok { + t.Error("Expected 'AHOST' key in the JSON, but it was not found") + } else { + // Example assertion: Check the "AHOST" src and val values + if ahost.Src != "l2env" { + t.Errorf(`Expected "src" value to be "l2env" for "AHOST", but got: %v`, ahost.Src) + } + if ahost.Val != "`echo http://httpbin.org`" { + t.Errorf("Expected \"val\" value to be \"`echo http://httpbin.org`\" for \"AHOST\", but got: %v", ahost.Val) + } + } + // Example assertion: Check the "BHOST" key + if bhost, ok := envMap["BHOST"]; !ok { + t.Error("Expected 'BHOST' key in the JSON, but it was not found") + } else { + // Example assertion: Check the "BHOST" src and val values + if bhost.Src != "l2configenv" { + t.Errorf(`Expected "src" value to be "l2configenv" for "BHOST", but got: %v`, bhost.Src) + } + if bhost.Val != "https://httpbin.org" { + t.Errorf(`Expected "val" value to be "https://httpbin.org" for "BHOST", but got: %v`, bhost.Val) + } + } + +} + + +func TestL2EnvCommand(t *testing.T) { + cmdArgs := []string{"-e", "../elfparser/ElfTestSuite/root_variable_override/api/y_0020_root_override.l2"} + runL2CommandAndParseJSON(t, cmdArgs...) +} + + +func TestL2EnvCommandVerbose(t *testing.T) { + cmdArgs := []string{"-ev", "../elfparser/ElfTestSuite/root_variable_override/api/y_0020_root_override.l2"} + runL2CommandAndParseJSON(t, cmdArgs...) +} \ No newline at end of file From ce1359c3000be816350fd5d1a7a73f001df3d99a Mon Sep 17 00:00:00 2001 From: lovestaco Date: Thu, 20 Jul 2023 09:22:34 +0530 Subject: [PATCH 18/23] Updating log to os.Stderr, logging --- outputManager/output_manager.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/outputManager/output_manager.go b/outputManager/output_manager.go index f6033733..d8d5bb2a 100644 --- a/outputManager/output_manager.go +++ b/outputManager/output_manager.go @@ -20,7 +20,7 @@ import ( var LogBuff bytes.Buffer func init() { - consoleWriter := zerolog.ConsoleWriter{Out: os.Stdout} + consoleWriter := zerolog.ConsoleWriter{Out: os.Stderr} consoleWriter2 := zerolog.ConsoleWriter{Out: &LogBuff} multi := zerolog.MultiLevelWriter(consoleWriter, consoleWriter2) logger := zerolog.New(multi).With().Timestamp().Logger() From 251ddef85c2474788e25d75edcd685aea331d76a Mon Sep 17 00:00:00 2001 From: lovestaco Date: Thu, 20 Jul 2023 09:27:53 +0530 Subject: [PATCH 19/23] Linting and adding verbose, test --- makefile | 2 +- tests/env_command_test.go | 15 ++++++--------- tests/multistage_test.go | 4 ++-- 3 files changed, 9 insertions(+), 12 deletions(-) diff --git a/makefile b/makefile index a32430dc..f9c1f3c4 100644 --- a/makefile +++ b/makefile @@ -24,7 +24,7 @@ gofumpt: test: make buildme - go test ./tests/ -count=1 + go test ./tests/ -count=1 -v benchmark: go test -bench=. -count 1 -run=^# -benchmem ./tests/ diff --git a/tests/env_command_test.go b/tests/env_command_test.go index 8fdbf7e1..ef426014 100644 --- a/tests/env_command_test.go +++ b/tests/env_command_test.go @@ -2,11 +2,11 @@ package tests import ( // "encoding/json" - "os/exec" - "testing" - "fmt" "bytes" "encoding/json" + "fmt" + "os/exec" + "testing" ) type EnvData struct { @@ -14,7 +14,7 @@ type EnvData struct { Val string `json:"val"` } -func runL2CommandAndParseJSON(t *testing.T, cmdArgs ...string) { +func runL2CommandAndParseJSON(t *testing.T, cmdArgs ...string) { cmd := exec.Command("../build/l2", cmdArgs...) var stdout bytes.Buffer cmd.Stdout = &stdout @@ -63,17 +63,14 @@ func runL2CommandAndParseJSON(t *testing.T, cmdArgs ...string) { t.Errorf(`Expected "val" value to be "https://httpbin.org" for "BHOST", but got: %v`, bhost.Val) } } - } - func TestL2EnvCommand(t *testing.T) { cmdArgs := []string{"-e", "../elfparser/ElfTestSuite/root_variable_override/api/y_0020_root_override.l2"} runL2CommandAndParseJSON(t, cmdArgs...) } - func TestL2EnvCommandVerbose(t *testing.T) { cmdArgs := []string{"-ev", "../elfparser/ElfTestSuite/root_variable_override/api/y_0020_root_override.l2"} - runL2CommandAndParseJSON(t, cmdArgs...) -} \ No newline at end of file + runL2CommandAndParseJSON(t, cmdArgs...) +} diff --git a/tests/multistage_test.go b/tests/multistage_test.go index a580b459..1b8f98ef 100644 --- a/tests/multistage_test.go +++ b/tests/multistage_test.go @@ -30,9 +30,9 @@ func TestMultiStageCount(t *testing.T) { for _, block := range parsedAPIblocks { blockType := block.S("type").Data().(string) if blockType == "processor" { - procCount ++ + procCount++ } else if blockType == "Lama2File" { - reqCount ++ + reqCount++ } } From cbe799ff344a843463e19900b0b299ed25dcf717 Mon Sep 17 00:00:00 2001 From: lovestaco Date: Thu, 20 Jul 2023 20:00:24 +0530 Subject: [PATCH 20/23] Adding env_command, test --- tests/env_command_test.go | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/tests/env_command_test.go b/tests/env_command_test.go index ef426014..32813473 100644 --- a/tests/env_command_test.go +++ b/tests/env_command_test.go @@ -1,12 +1,13 @@ package tests import ( - // "encoding/json" "bytes" "encoding/json" "fmt" "os/exec" "testing" + "os" + ) type EnvData struct { @@ -15,15 +16,27 @@ type EnvData struct { } func runL2CommandAndParseJSON(t *testing.T, cmdArgs ...string) { - cmd := exec.Command("../build/l2", cmdArgs...) + // Get the full path to the l2 binary + l2BinPath := "/home/runner/work/Lama2/Lama2/build/l2" + + // Check if the l2 binary file exists + if _, err := os.Stat(l2BinPath); os.IsNotExist(err) { + fmt.Printf("Error: l2 binary not found in the build folder %s, please change the path.\n", l2BinPath) + return + } + + // Your existing code to run the l2 command and parse JSON + cmd := exec.Command(l2BinPath, cmdArgs...) + var stdout bytes.Buffer cmd.Stdout = &stdout - + // Execute the command err := cmd.Run() if err != nil { - // Handle the error if needed + // Handle the error if needed fmt.Printf("Error running l2 command: %v\n", err) + return } // Retrieve the captured stdout @@ -39,6 +52,7 @@ func runL2CommandAndParseJSON(t *testing.T, cmdArgs ...string) { if err != nil { t.Fatalf("Error unmarshaling JSON: %v\nOutput:\n%s", err, stdoutOutput) } + // Example assertion: Check the "AHOST" key if ahost, ok := envMap["AHOST"]; !ok { t.Error("Expected 'AHOST' key in the JSON, but it was not found") @@ -65,6 +79,7 @@ func runL2CommandAndParseJSON(t *testing.T, cmdArgs ...string) { } } + func TestL2EnvCommand(t *testing.T) { cmdArgs := []string{"-e", "../elfparser/ElfTestSuite/root_variable_override/api/y_0020_root_override.l2"} runL2CommandAndParseJSON(t, cmdArgs...) From 58fbc92c91241606cbee4af429c53b4c54b0224d Mon Sep 17 00:00:00 2001 From: lovestaco Date: Thu, 20 Jul 2023 20:16:54 +0530 Subject: [PATCH 21/23] Updating testapp.yml, build and test --- .github/workflows/testapp.yml | 5 ++- tests/env_command_test.go | 66 +++++++++++++++++++++++------------ 2 files changed, 47 insertions(+), 24 deletions(-) diff --git a/.github/workflows/testapp.yml b/.github/workflows/testapp.yml index 2c78a4d0..248c4df6 100644 --- a/.github/workflows/testapp.yml +++ b/.github/workflows/testapp.yml @@ -18,6 +18,9 @@ jobs: - name: Build run: go build -v ./... - name: Test with the Go CLI - run: go test -v ./tests/ + run: | + go mod tidy + go build -o build/l2 -ldflags "-X main.version=`git tag --sort=-version:refname | head -n 1`" l2.go + go test -v ./tests/ - name: Deploy hexmos doc run: curl -X POST --fail -F token=${{ secrets.TRIGGER_TOKEN }} -F ref=main https://git.apps.hexmos.com/api/v4/projects/85/trigger/pipeline \ No newline at end of file diff --git a/tests/env_command_test.go b/tests/env_command_test.go index 32813473..19f9b335 100644 --- a/tests/env_command_test.go +++ b/tests/env_command_test.go @@ -4,10 +4,11 @@ import ( "bytes" "encoding/json" "fmt" + "os" "os/exec" "testing" - "os" + "github.com/rs/zerolog/log" ) type EnvData struct { @@ -15,34 +16,44 @@ type EnvData struct { Val string `json:"val"` } +func TestL2EnvCommand(t *testing.T) { + cmdArgs := []string{"-e", "../elfparser/ElfTestSuite/root_variable_override/api/y_0020_root_override.l2"} + runL2CommandAndParseJSON(t, cmdArgs...) +} + +func TestL2EnvCommandVerbose(t *testing.T) { + cmdArgs := []string{"-ev", "../elfparser/ElfTestSuite/root_variable_override/api/y_0020_root_override.l2"} + runL2CommandAndParseJSON(t, cmdArgs...) +} + func runL2CommandAndParseJSON(t *testing.T, cmdArgs ...string) { // Get the full path to the l2 binary l2BinPath := "/home/runner/work/Lama2/Lama2/build/l2" // Check if the l2 binary file exists - if _, err := os.Stat(l2BinPath); os.IsNotExist(err) { - fmt.Printf("Error: l2 binary not found in the build folder %s, please change the path.\n", l2BinPath) + if err := checkL2BinaryExists(l2BinPath); err != nil { + t.Error(err) return } // Your existing code to run the l2 command and parse JSON cmd := exec.Command(l2BinPath, cmdArgs...) - + var stdout bytes.Buffer cmd.Stdout = &stdout - + // Execute the command err := cmd.Run() if err != nil { - // Handle the error if needed - fmt.Printf("Error running l2 command: %v\n", err) + // Handle the error if needed + t.Errorf("Error running l2 command: %v\n", err) return } // Retrieve the captured stdout stdoutOutput := stdout.String() - fmt.Println(stdoutOutput) + log.Debug().Str("Test env_command", stdoutOutput).Msg("output from command") // Convert the stdoutOutput string to []byte slice outputBytes := []byte(stdoutOutput) @@ -50,10 +61,27 @@ func runL2CommandAndParseJSON(t *testing.T, cmdArgs ...string) { envMap := make(map[string]EnvData) err = json.Unmarshal(outputBytes, &envMap) if err != nil { - t.Fatalf("Error unmarshaling JSON: %v\nOutput:\n%s", err, stdoutOutput) + t.Fatalf("Error unmarshaling JSON env: %v\nOutput:\n%s", err, stdoutOutput) + } + + // Check the "AHOST" key + checkAHost(t, envMap) + + // Check the "BHOST" key + checkBHost(t, envMap) +} + +// checkL2BinaryExists checks if the l2 binary file exists in the specified path +func checkL2BinaryExists(l2BinPath string) error { + // Check if the l2 binary file exists + if _, err := os.Stat(l2BinPath); os.IsNotExist(err) { + return fmt.Errorf("l2 binary not found in the build folder %s, please change the path", l2BinPath) } + return nil +} - // Example assertion: Check the "AHOST" key +// checkAHost checks the "AHOST" key in the JSON map +func checkAHost(t *testing.T, envMap map[string]EnvData) { if ahost, ok := envMap["AHOST"]; !ok { t.Error("Expected 'AHOST' key in the JSON, but it was not found") } else { @@ -62,10 +90,13 @@ func runL2CommandAndParseJSON(t *testing.T, cmdArgs ...string) { t.Errorf(`Expected "src" value to be "l2env" for "AHOST", but got: %v`, ahost.Src) } if ahost.Val != "`echo http://httpbin.org`" { - t.Errorf("Expected \"val\" value to be \"`echo http://httpbin.org`\" for \"AHOST\", but got: %v", ahost.Val) + t.Errorf(`Expected "val" value to be "echo http://httpbin.org" for "AHOST", but got: %v`, ahost.Val) } } - // Example assertion: Check the "BHOST" key +} + +// checkBHost checks the "BHOST" key in the JSON map +func checkBHost(t *testing.T, envMap map[string]EnvData) { if bhost, ok := envMap["BHOST"]; !ok { t.Error("Expected 'BHOST' key in the JSON, but it was not found") } else { @@ -78,14 +109,3 @@ func runL2CommandAndParseJSON(t *testing.T, cmdArgs ...string) { } } } - - -func TestL2EnvCommand(t *testing.T) { - cmdArgs := []string{"-e", "../elfparser/ElfTestSuite/root_variable_override/api/y_0020_root_override.l2"} - runL2CommandAndParseJSON(t, cmdArgs...) -} - -func TestL2EnvCommandVerbose(t *testing.T) { - cmdArgs := []string{"-ev", "../elfparser/ElfTestSuite/root_variable_override/api/y_0020_root_override.l2"} - runL2CommandAndParseJSON(t, cmdArgs...) -} From 2b505fc4cefc6630e3cf8231231f86d4fcafe462 Mon Sep 17 00:00:00 2001 From: lovestaco Date: Thu, 20 Jul 2023 20:28:57 +0530 Subject: [PATCH 22/23] Relative path for binary, test --- tests/env_command_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/env_command_test.go b/tests/env_command_test.go index 19f9b335..f48b6009 100644 --- a/tests/env_command_test.go +++ b/tests/env_command_test.go @@ -28,7 +28,7 @@ func TestL2EnvCommandVerbose(t *testing.T) { func runL2CommandAndParseJSON(t *testing.T, cmdArgs ...string) { // Get the full path to the l2 binary - l2BinPath := "/home/runner/work/Lama2/Lama2/build/l2" + l2BinPath := "../build/l2" // Check if the l2 binary file exists if err := checkL2BinaryExists(l2BinPath); err != nil { From 312d5bda9a5fa225936c9ab14f6bce726ef5c731 Mon Sep 17 00:00:00 2001 From: lovestaco Date: Thu, 20 Jul 2023 21:16:10 +0530 Subject: [PATCH 23/23] Fixing all errors, linting --- parser/jsonparser.go | 3 ++- preprocess/expandvar.go | 1 + preprocess/preprocess.go | 2 +- tests/lama2_test.go | 3 --- 4 files changed, 4 insertions(+), 5 deletions(-) diff --git a/parser/jsonparser.go b/parser/jsonparser.go index 62112b0a..d4edf9e8 100644 --- a/parser/jsonparser.go +++ b/parser/jsonparser.go @@ -25,7 +25,8 @@ 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(_, source interface{}) interface{} { +//nolint:all +func CustomPairMerge(destination, source interface{}) interface{} { return source } diff --git a/preprocess/expandvar.go b/preprocess/expandvar.go index 70a638e7..9c723655 100644 --- a/preprocess/expandvar.go +++ b/preprocess/expandvar.go @@ -27,6 +27,7 @@ func Expand(s string, vm *goja.Runtime, mapping map[string]string) string { } buf = append(buf, s[i:j]...) name, w := getShellName(s[j+1:]) + //nolint:all if name == "" && w > 0 { // Encountered invalid syntax; eat the // characters. diff --git a/preprocess/preprocess.go b/preprocess/preprocess.go index 4f3b0d4c..96486ea0 100644 --- a/preprocess/preprocess.go +++ b/preprocess/preprocess.go @@ -73,7 +73,7 @@ func debugOp(str string) { func escapeString(input string) string { output, err := json.Marshal(input) if err != nil { - // handle error + log.Error().Str("Error marshaling JSON:","escapeString()") } return string(output) } diff --git a/tests/lama2_test.go b/tests/lama2_test.go index 9da7b359..e73f361d 100644 --- a/tests/lama2_test.go +++ b/tests/lama2_test.go @@ -63,9 +63,6 @@ func PerformParserMatch(text string) (*gabs.Container, error) { got, e := p.Parse(text) if e == nil { log.Debug().Str("Got", got.String()).Msg("") - } else { - // t.Errorf("Error not expected") - // fmt.Println(e) } return got, e }