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

GoCI - Trying to use otto js parser in my project #185

Closed
paulocoutinhox opened this issue May 3, 2016 · 11 comments
Closed

GoCI - Trying to use otto js parser in my project #185

paulocoutinhox opened this issue May 3, 2016 · 11 comments

Comments

@paulocoutinhox
Copy link

Hi,

I have a project called GoCI:
https://github.com/prsolucoes/goci

This project use Anko script parser in Go to make the CI builds. Users can create a script.ank file to execute every process need to build a task.

My questions is about how i can do the same things using otto js parser. What i need understand in otto js parser:

1 - Export Go functions to javascript, like make http request, exec command line, get environment vars ... everything here:
https://github.com/prsolucoes/goci

2 - I need export my own package called "goci". This custom package has some goci system functions, some variables, etc. There is a way to export it as object? Like "var job = goci.Job"!

3 - If script crash/error, i can get this status without crash all the "goci" process ?

Thanks for the help!

@deoxxa
Copy link
Collaborator

deoxxa commented May 3, 2016

1a) It's very easy to provide Go functions to the JavaScript interpreter in otto.

vm := otto.New()
vm.Set("helloGo", func() { fmt.Printf("hello!\n") })
vm.Run(`helloGo()`)

1b) integrating HTTP requests in a way that feels familiar to JavaScript is difficult. Synchronous HTTP is easy, asynchronous HTTP is hard. I've written a library for doing asynchronous HTTP (and other things!) - fknsrs.biz/p/ottoext.

  1. It's also pretty easy to export something like goci to the interpreter
vm := otto.New()
vm.Set("goci", map[string]interface{}{
  "Job": goci.Job,
  "NewThing": func() goci.Thing { return goci.Thing{} },
})
vm.Run(`var thing = goci.NewThing()`)
vm.Run(`var job = goci.Job`)
  1. Run returns (Value, error) - if an exception is thrown in the JavaScript program, err will be non-nil.

I have an article you might be interested in - getting started with otto.

Please feel free to ask if you have any more questions!

@paulocoutinhox
Copy link
Author

Yes,

My question about bult-in functions dont have an answer :p kidding

All golang packages are exported to JS with otto? There is any repository with this work - golang packages exported to otto?

Thanks.

@deoxxa
Copy link
Collaborator

deoxxa commented May 4, 2016

By default, no - only the JavaScript standard library is available. Otto is often used to execute untrusted code, and you probably don't want untrusted code being able to interact with the filesystem etc.

You can pretty easily provide specific things to the interpreter though, as I showed above.

Here's an example of exposing a function for making simple HTTP requests (please don't use this function in production!)

vm := otto.New()

vm.Set("httpGet", func(s string) string {
  r, err := http.Get(s)
  if err != nil {
    panic(vm.MakeCustomError("IOError", "failed making http request"))
  }

  d, err := ioutil.ReadAll(r.Body)
  if err != nil {
    panic(vm.MakeCustomError("IOError", "failed reading body"))
  }

  return string(d)
})

code := `
  var data = httpGet('http://www.google.com/');
  console.log(data);
`

if _, err := vm.Run(code); err != nil {
  fmt.Printf("error: %s\n", err.Error())
}

@paulocoutinhox
Copy link
Author

I dont know if is a problem on otto or mine. Can you check?

Im exporting golang packages to otto:

vm.Set("http", map[string]interface{}{
"Get": http.Get,
"Post": http.Post,
"PostForm": http.PostForm,
"NewRequest": http.NewRequest,
})

Im trying call from JS with few method arguments to check error handling:

console.log(http.Post("https://httpbin.org/post"));

This method require 3 args and i set only one in js file. A panic error happen and process is stopped :(

panic: reflect: Call with too few input arguments [recovered]
panic: reflect: Call with too few input arguments

goroutine 13 [running]:
panic(0x5fbdc0, 0xc8203482d0)
/usr/local/Cellar/go/1.6/libexec/src/runtime/panic.go:464 +0x3e6

Could you help me?

@deoxxa
Copy link
Collaborator

deoxxa commented May 4, 2016

That certainly looks like a bug. I reckon that should be a JavaScript TypeError or RangeError exception, not a panic that takes down the host program.

@paulocoutinhox
Copy link
Author

I test it with too many args and with few args, and panic error is generated.

I made another test, creating my own function:

vm.Set("goci", map[string]interface{}{
"ByteArrayToString": func (a []byte) string {
return string(a)
},
})

When i call from javascript, with invalid params, another panic:

console.log(goci.ByteArrayToString(myByteArray, "aaa"));

Error:

panic: cannot use aaa as type []uint8 [recovered]
panic: cannot use aaa as type []uint8

With only the first parameter no problems happen, it is the correct type - but the second generate panic and crash all.

@paulocoutinhox
Copy link
Author

Another question now:

For functions that return more than one return type, ex (string, err). How we can threat it on javascript? Because today it is returning an Object, and i get with index [0], [1], ...

Have bult-in solution?

@deoxxa
Copy link
Collaborator

deoxxa commented May 4, 2016

Right now it'll return an array. JavaScript doesn't have multiple return values, so that's about as good as it gets. One day otto might get some support for ES6 stuff (like destructuring assignments), but right now you just have to use the array. Either that or write wrapper functions that make things work more like JavaScript usually does, like the code I posted above.

@paulocoutinhox
Copy link
Author

paulocoutinhox commented May 4, 2016

Ok...can you solve only the problems about params (invalid, less and too many) to i continue working on integration? Thanks! My email: paulo[@]prsolucoes.com

@deoxxa
Copy link
Collaborator

deoxxa commented May 4, 2016

Eventually, yep! But you have to remember, nobody is getting paid for this - so it might take some time. I'll close #186 when it's fixed.

@deoxxa deoxxa closed this as completed May 4, 2016
@paulocoutinhox
Copy link
Author

paulocoutinhox commented May 4, 2016

Ok, no problem. All my open-source projects is not paid too :)
Can you give me only your skype/hangout/email to talk? I want collab too. My email/skype/hangout: paulo[at]prsolucoes.com

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants