Skip to content
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

Merged
merged 23 commits into from
Jul 20, 2023
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
cca4db6
search and load l2config.env file
lovestaco Jul 9, 2023
0c87717
consolidating LoadElfEnv and LoadConfigEnv
lovestaco Jul 9, 2023
84a4848
Adding comments for LoadEnvironments function
lovestaco Jul 10, 2023
4dd0f23
Updating documentation with global variable support
lovestaco Jul 10, 2023
655a236
examples.md
lovestaco Jul 12, 2023
548e43e
Updating preprocess, documentation
lovestaco Jul 12, 2023
48f3154
Updating architecture, documentation
lovestaco Jul 12, 2023
d12b69b
Updating l2format, documentation
lovestaco Jul 12, 2023
549affb
Adding command to get JSON of envs
lovestaco Jul 16, 2023
a66383b
Updating l2format and examples, documentation
lovestaco Jul 16, 2023
be15f49
Search l2configenv from the l2file level
lovestaco Jul 17, 2023
a1b1b33
Pure functions for GetL2EnvVariables
lovestaco Jul 18, 2023
caece11
Updating documentation
lovestaco Jul 18, 2023
36d2d4f
Make lint and gofumpt, lint errors
lovestaco Jul 18, 2023
ffc95e9
Adding varjson variable example, documentation
lovestaco Jul 18, 2023
82690f1
Adding root override and backtick echo var, test
lovestaco Jul 19, 2023
c19afee
Adding env_command, test
lovestaco Jul 20, 2023
ce1359c
Updating log to os.Stderr, logging
lovestaco Jul 20, 2023
251ddef
Linting and adding verbose, test
lovestaco Jul 20, 2023
cbe799f
Adding env_command, test
lovestaco Jul 20, 2023
58fbc92
Updating testapp.yml, build and test
lovestaco Jul 20, 2023
2b505fc
Relative path for binary, test
lovestaco Jul 20, 2023
312d5bd
Fixing all errors, linting
lovestaco Jul 20, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 2 additions & 5 deletions codegen/codegen.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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()

Expand Down
8 changes: 4 additions & 4 deletions controller/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -89,13 +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
}
log.Info().Str("Type", "Preprocess").Msg("Env Variables:\n" + string(jsonEnvs))
return
// Frontend can read the stdout for this command and get the JSON of all the env's
fmt.Println(string(jsonEnvs))
Copy link
Contributor

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.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes works.
image

return
}

preprocess.LoadEnvironments(dir)
Expand Down
46 changes: 36 additions & 10 deletions docs/Lama2/docs/explanation/l2format.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 `#`
Expand Down Expand Up @@ -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`
Expand All @@ -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`:

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Screenshot needed to show project structure, and root.

```
Expand All @@ -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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

*residing


Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Must show full example here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The 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
Expand All @@ -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:
Expand Down
2 changes: 1 addition & 1 deletion docs/Lama2/docs/reference/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
2 changes: 1 addition & 1 deletion docs/Lama2/docs/reference/preprocess.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand Down
14 changes: 7 additions & 7 deletions docs/Lama2/docs/tutorials/examples.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -85,22 +85,22 @@ 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**

```
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

Expand Down Expand Up @@ -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.

```
Expand Down Expand Up @@ -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.
Expand Down
24 changes: 24 additions & 0 deletions examples/0021_varjson_variable/0021_varjson_variable.l2
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}",
}
3 changes: 1 addition & 2 deletions lama2cmd/lama2cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion parser/jsonparser.go
Original file line number Diff line number Diff line change
Expand Up @@ -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{} {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why rename this in jsonparser?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was erroring out in the make lint

return source
}

Expand Down
1 change: 0 additions & 1 deletion parser/lama2parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -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]*

Expand Down
4 changes: 2 additions & 2 deletions preprocess/expandvar.go
Original file line number Diff line number Diff line change
Expand Up @@ -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++ {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why comment this? If lines not needed, should be deleted.

// }
return s[:i], i
}

Expand Down
50 changes: 37 additions & 13 deletions preprocess/preprocess.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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")
}
}

Expand Down Expand Up @@ -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{} {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add a comment regarding desired order for l2config.env and l2.env in this case. What overwrites what?

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
}

Expand Down
2 changes: 0 additions & 2 deletions tests/base64_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -43,5 +42,4 @@ func TestBase64(t *testing.T) {
fmt.Println(block)
}
utils.ChangeWorkingDir(nowPwd)

}
2 changes: 1 addition & 1 deletion tests/importer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"))
Expand Down
2 changes: 1 addition & 1 deletion tests/js_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Expand Down
Loading