Skip to content

Playground: Gist support #6

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
ajhager opened this issue Oct 31, 2014 · 32 comments · Fixed by #11
Closed

Playground: Gist support #6

ajhager opened this issue Oct 31, 2014 · 32 comments · Fixed by #11
Assignees

Comments

@ajhager
Copy link

ajhager commented Oct 31, 2014

We do not support sharing directly from the playground, since it is all client side. Adding the ability to load Github gists or Golang playground code by id should help fill in that gap.

We also might be able to add a route in angularjs like /playground/[gist-id] that automatically loads the code from the gist with that id.

@ajhager ajhager self-assigned this Oct 31, 2014
@dmitshur
Copy link
Member

dmitshur commented Nov 1, 2014

GitHub API allows CORS, so fetching the gist contents from a gist id can be done in the frontend as easily as this:

gistUrl := "https://api.github.com/gists/" + gistId

data, err := xhr.Send("GET", gistUrl, nil)
if err != nil {
    return err
}

var gistJson struct {
    Files map[string]struct{ Content string }
}
err = json.Unmarshal([]byte(data), &gistJson)
if err != nil {
    return err
}

for filename, file := range gistJson.Files {
    // Use file.Content
}

@ajhager
Copy link
Author

ajhager commented Nov 1, 2014

That is excellent. Cheers!

@neelance
Copy link
Member

neelance commented Nov 2, 2014

Relevant: gopherjs/gopherjs#95

@ajhager
Copy link
Author

ajhager commented Nov 2, 2014

Alright, I have gist support working, but I am trying to come up with a strategy.

  1. There is one file in the Gist and it is a go file: Load the file into the editor.
  2. There are multiple files and only one is a go file: See 1.
  3. There are multiple files and none are go files: Error
  4. There are multiple files and more than one are go files: Which gets put in the editor? Do we compile all the go files as the main package.
  5. Check that there is only 1 file and it is in Go: Display errors if the gist doesn't conform.

My instinct says 5. We don't want to support multiple files in the editor, and multiple go files in a gist might not even be related or in the same package.

Thoughts?

@dominikh
Copy link
Member

dominikh commented Nov 2, 2014

I'd keep it simple and allow exactly one file in the gist and load that file. I wouldn't necessarily check that it's a Go file, as people or tools might be lazy and push unnamed and untyped files as gists.

@ajhager
Copy link
Author

ajhager commented Nov 2, 2014

That is a good point. If the user wants to load up some Scala code and try to compile it, it isn't going to hurt anything anyway.

@dmitshur
Copy link
Member

dmitshur commented Nov 2, 2014

I think it'd be helpful to take a step back and think about the problem as a whole.

Ideally, what we want is something like what play.golang.org offers, the ability to take current content (something the person likely iterated on after running it multiple times within the playground) and save/share it, then reload it from that url.

The ability to load gists is secondary to that, because from what I can tell, saving gists is far from a quick experience (you have to select all text in the playground, copy it, open a new tab, go to gists.github.com, login to github if you're not, paste, press a button). So it's unlikely there will be interesting things to load from gists.

Unless we leverage the GitHub API to save anonymous gists from the GopherJS playground in one button press. At that point, it simply becomes the storage we use for programs.

I guess what I'm suggesting is that it's important to consider both the saving and loading experience together.

That said, I agree with the above, it's probably best to keep it as simple as possible and allow one file. Also, if we implement saving to gists, then you know what to expect when loading.

@dmitshur
Copy link
Member

dmitshur commented Nov 2, 2014

If play.golang.org has any sort of API that would allow us to fetch/save contents, I would argue that is the best storage to (re)use, since then a play.golang.org/p/-URiXol0GB URL can be transformed to gopherjs.org/play/-URiXol0GB and to load the exact the same program (and vice versa).

But I'm not sure we can do that.

@neelance
Copy link
Member

neelance commented Nov 2, 2014

I inspected play.golang.org and it seems like saving is just a simple POST request:

curl --data "GopherJS!" http://play.golang.org/share

For loading we would need to extract the content of the textarea returned by

curl play.golang.org/p/swRNzuPJlS

It's possible to do that, but I feel like we should ask the Go team first, maybe at the golang-dev mailing list.

@ajhager
Copy link
Author

ajhager commented Nov 2, 2014

I was originally coming at it only from the idea of loading a gist, not sharing from the playground. I absolutely agree that using the Go playground like that would be super cool. Would you like to ask about that Richard? It might look better coming from the creator of GopherJS.

Anonymous gists seems like it would be wasteful, since it would be impossible to associate the code in the editor with an gist id. No matter how many times someone shares, for example, the default code, a new gist would be created. Also, there is a 60 anon gists per hour limit I believe.

@dominikh
Copy link
Member

dominikh commented Nov 2, 2014

For loading we would need to extract the content of the textarea returned by

Append .go to the URL:

curl play.golang.org/p/swRNzuPJlS.go

@neelance
Copy link
Member

neelance commented Nov 2, 2014

Nice!

@ajhager
Copy link
Author

ajhager commented Nov 2, 2014

I assume they will say it is ok. Other tools, like editor plugins, use the service like that already.

@neelance
Copy link
Member

neelance commented Nov 2, 2014

Okay, then let's add it to our playground. It will be great!

@dominikh
Copy link
Member

dominikh commented Nov 2, 2014

The rule generally is that you ask/let the Go team know that you intend to use the playground in your service. Admittedly, they primarily care due to code compilation, not the pastebin aspect, but at least letting them know sounds like a nice thing to do.

The playground service is used by more than just the official Go project (Go by Example is one other instance) and we are happy for you to use it on your own site. All we ask is that you contact us first, use a unique user agent in your requests (so we can identify you), and that your service is of benefit to the Go community.

@neelance
Copy link
Member

neelance commented Nov 2, 2014

I guess we might need a Access-Control-Allow-Origin header from their side to make cross domain requests. @ajhager Can you look into this? If yes, then we can ask that in the same message to golang-dev.

@ajhager
Copy link
Author

ajhager commented Nov 2, 2014

Sure, give me a few minutes. I am adding and testing it right now.

@ajhager
Copy link
Author

ajhager commented Nov 2, 2014

Indeed, I am getting the Access-Control-Allow-Origin error. Looks like we will have to ask for that if this is going to work.

@dmitshur
Copy link
Member

dmitshur commented Nov 2, 2014

... if this is going to work.

For it to work completely from the frontend. CORS isn't a concern if done in the backend.

Of course, we should absolutely ask for permission/let them know regardless of whether there are technical adjustments to be made or not, as @dominikh pointed out in #6 (comment).

@ajhager
Copy link
Author

ajhager commented Nov 2, 2014

I really can't anticipate how they will respond. Seems like a slippery slope if they open up for us. It would also make it hard to test locally. It would be awesome if they just had a simple JSON api. :)

For now I will keep the Gist support, and we can revisit this when we know more.

@dmitshur
Copy link
Member

dmitshur commented Nov 3, 2014

I really can't anticipate how they will respond.

We'll never know if we don't ask. Given that "and that your service is of benefit to the Go community" IMO is satisfied, I think our chances are pretty good.

@neelance, are you going to post on the mailing list (probably the golang-dev one)? Or would you like one of us to do that.

Edit: We only want to use the pastebin aspect of the API, which is less computationally expensive than using the compile and execute Go code part... I think that should hopefully improve our chances.

@dmitshur
Copy link
Member

dmitshur commented Jan 4, 2015

Ping @neelance. I'd like to make progress on this issue.

Again, I believe that with all factors considered, we have a pretty decent chance of getting a "yes" response.

Would you like to post the question @neelance, or would you prefer I do it on your behalf?

@neelance
Copy link
Member

neelance commented Jan 4, 2015

Yes, please go ahead.

@dmitshur
Copy link
Member

dmitshur commented Jan 4, 2015

I've done so here.

@dmitshur
Copy link
Member

dmitshur commented Jan 5, 2015

Well, we have partial success!

https://groups.google.com/d/msg/golang-dev/zSK8WhhiYDE/tub0B5svp9wJ

@adg said we're okay to load snippets from Go playground, but we shouldn't store new ones there.

I'm guessing they're not yet very familiar with GopherJS and the kind of Go programs/snippets it's likely to compile, so they don't want those unknown programs polluting the namespace, which is fair (and I'm sure the decision can be revisited in the future once the unknowns become more known). It's possible many will use the github.com/gopherjs/gopherjs/js package.

Since we will definitely need a backend to store the snippets, there's not much point in asking for CORS for loading, as the backend can simply forward that along.

It seems that we'll need a simple backend for storing GopherJS playground Go code snippets. It doesn't seem very hard to create. I can volunteer to do it.

The main requirements would be:

  • generate/reuse same IDs for previously shared inputs,
  • try to avoid collisions between IDs coming from Go playground with ones we create ourselves.

Am I missing anything?

@dmitshur
Copy link
Member

dmitshur commented Jan 5, 2015

Separately, we need to decide on a frontend URL scheme. How about:

http://play.golang.org/p/D9L6MbPfE4
http://gopherjs.org/play/?p=D9L6MbPfE4

(Since the playground is served as part of a static website, as far as I know, it has to be a query parameter. Correct?)

@dmitshur
Copy link
Member

dmitshur commented Jan 6, 2015

@dmitshur
Copy link
Member

dmitshur commented Jan 6, 2015

I'm working on this now (@ajhager, feel free to assign this issue to me; I can't because I don't have push rights for this repo), quick question for @ajhager or @neelance:

Is it okay if I use honnef.co/go/js/dom and honnef.co/go/js/xhr packages in the playground.go source code? Right now I'm not using them because the package doesn't already import them, but it would be nice if I could.

@dmitshur
Copy link
Member

dmitshur commented Jan 6, 2015

Ok, I have this working and pretty close to done. The backend component is almost done, just needs final review. The frontend components works, but needs to be cleaned up and use AngularJS better.

The PR for the backend component ready for final review, see gopherjs/snippet-store#1.

The PR for the frontend change is very rough, and has lots of TODOs and code cleanup remaining, but just to get the process started, see PR #11.

I've setup a temporary copy of the playground where you can test out the snippet loading/saving, etc. The compiling doesn't work because I didn't update the compiler files but my gopherjs is newer. Compiling is unrelated to snippet loading/sharing so it doesn't matter.

http://dmitri.shuralyov.com/temp/playground/index.html
http://dmitri.shuralyov.com/temp/playground/index.html#/Fi6ixjyYo_ (snippet from local storage)
http://dmitri.shuralyov.com/temp/playground/index.html#/D9L6MbPfE4 (snippet from Go Playground)

image

There are some minor usability bugs to iron out with the frontend (see PR for details), but it should mostly work. Let me know what you think!

@neelance
Copy link
Member

neelance commented Jan 6, 2015

@shurcooL I'll give you push rights to this repo.
@dominikh I've seen that you have already done some code review. Thx.
@shurcooL @dominikh @ajhager Is it okay for you guys if I leave this up to you? I don't have so much time and I would like to spend it on improving GopherJS itself. I'm sure you'll come up with a great solution. One suggestion anyway: We can use https://www.heroku.com/ for running the server. Their smallest usage tier is free and it should be enough. I have used https://github.com/kr/heroku-buildpack-go before and it worked really well.

@neelance
Copy link
Member

neelance commented Jan 6, 2015

@shurcooL

Is it okay if I use honnef.co/go/js/dom and honnef.co/go/js/xhr packages in the playground.go source code? Right now I'm not using them because the package doesn't already import them, but it would be nice if I could.

I think it should be okay.

@dmitshur
Copy link
Member

This is done and deployed. I've immediately found a minor issue #14, and fixed it in #15.

http://gopherjs.org/play/#/Myqj0bQVev is the first official GopherJS Playground snippet. Feel free to share your snippets, and please report any issues if you find any! We want the experience to be nothing short of delightful.

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

Successfully merging a pull request may close this issue.

4 participants