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

Use Octokit to fetch Gist content when passed a GItHub token #28

Merged
merged 13 commits into from
Dec 1, 2015
Merged

Conversation

benbalter
Copy link
Contributor

Fixes #27

(Should work, but having trouble getting tests to run locally)

@benbalter benbalter self-assigned this Nov 30, 2015
private

def code_from_api(gist_id, filename = nil)
return unless ENV["JEKYLL_GITHUB_TOKEN"]
Copy link
Member

Choose a reason for hiding this comment

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

Could this just be GITHUB_TOKEN?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I was going off the token Jekyll metadata used, so that you'd only have to set it once?

Copy link
Member

Choose a reason for hiding this comment

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

Good idea. I was thinking about other programs that use Octokit and what they use. Let's do JEKYLL_GITHUB_TOKEN for now – I think parity with jekyll-github-metadata for now makes sense. :) Thanks, Ben!

@parkr
Copy link
Member

parkr commented Nov 30, 2015

but having trouble getting tests to run locally

Sorry about this. Remove line 10 from spec/spec_helper.rb – that should help. That line swallowed errors.

@parkr parkr added this to the 1.4.0 milestone Nov 30, 2015
@benbalter
Copy link
Contributor Author

That line swallowed errors.

uninitialized constant Jekyll::Gist::GistTag::Octokit

Duh.

@benbalter
Copy link
Contributor Author

Got tests to pass. Two changes to note, thinking through things:

  1. If a token is supplied, and the API call fails, don't fallback to /raw (this wouldn't fix the DDoS problem described in the original issue if the API call fails due to, e.g., a 500 or a timeout).
  2. If the API call fails, fail loudly (e.g., if it's a bad token, the Gist doesn't exist, etc.). Again, why make two bad calls when you can just make one.

@parkr
Copy link
Member

parkr commented Dec 1, 2015

why make two bad calls when you can just make one.

To make things work more seamlessly. If Octokit is enabled (via the env var), then failing loudly on a bad config makes sense. And failing if the resource doesn't exist makes sense in both cases.

CI is erroring out on Jekyll 2 and Ruby 1.9.3:

  1) Jekyll::Gist::GistTag valid gist with token with a filename produces the noscript tag
     Failure/Error: expect(output).to match(/<noscript><pre>puts &#39;hello world&#39;<\/pre><\/noscript>/)

       expected "<noscript><pre>puts 'hello world'</pre></noscript>\n<script src=\"https://gist.github.com/1342013.js?file=hello-world.rb\"> </script>\n\n" to match /<noscript><pre>puts &#39;hello world&#39;<\/pre><\/noscript>/
       Diff:
       @@ -1,2 +1,3 @@
       -/<noscript><pre>puts &#39;hello world&#39;<\/pre><\/noscript>/
       +<noscript><pre>puts 'hello world'</pre></noscript>
       +<script src="https://gist.github.com/1342013.js?file=hello-world.rb"> </script>

Looks like the dumb quotes aren't being escaped there.

@benbalter
Copy link
Contributor Author

Looks like the output is different on Ruby 1.9? Should I make the test conditional? What's the "proper" way to do this?

@parkr
Copy link
Member

parkr commented Dec 1, 2015

Looks like the output is different on Ruby 1.9?

I think this is the problem 👆 The output shouldn't differ if you use a different Ruby. That's not The Jekyll Way ™️ . Ideally, we'd find a way to ensure it's the same output.

@benbalter
Copy link
Contributor Author

The output shouldn't differ if you use a different Ruby.

Looks like it's a change in how CGI.escapeHTML behaves < Ruby 2.0..

Coded around it to keep the behavior the same in 87b93ed.

private

def code_from_api(gist_id, filename = nil)
client = Octokit::Client.new :access_token => ENV["JEKYLL_GITHUB_TOKEN"]
Copy link
Member

Choose a reason for hiding this comment

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

Can this be cached so it can be reused?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done via d9c695f.

@parkr
Copy link
Member

parkr commented Dec 1, 2015

One optimization above, then LGTM. Thanks so much, @benbalter!

@benbalter
Copy link
Contributor Author

💚

end

def client
@client ||= Octokit::Client.new :access_token => ENV["JEKYLL_GITHUB_TOKEN"]
Copy link
Member

Choose a reason for hiding this comment

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

Whoops, I'm awfully silly. Really sorry, Ben, I misspoke. When I asked about caching, my reasoning was that for each {% gist %}, a new GistTag instance is created and thus requires its own client. The Client won't change between various gist calls, so storing it so it's on the class rather than instance (or similar, store it anywhere you feel is appropriate) gives us a little speed boost and relieves some pressure on the garbage collector.

Does that make sense? Sorry I didn't communicate all that. Still figuring out the right balance between being concise (saves time) and communicating 100% of what I was thinking.

So this code would become:

def self.client
  @client ||= Octokit::Client.new #...
end

and would be accessed via GistTag.client (i.e. at the class level).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Makes total sense. Didn't think through that. Does it need to be @@client?

Copy link
Member

Choose a reason for hiding this comment

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

Does it need to be @@client?

No, in the case of @client, it's an Instance variable on the Singleton. @@client is a class variable on GistTag, @client is an instance variable on the Singleton instance of GistTag. It's equivalent to:

class GistTag
  @client = Octokit::Client.new #...
end

Ruby is hella weird but there are fun nuances like this that keep things interesting. 😉

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Huh. 📚. Implemented via af85461.

parkr added a commit that referenced this pull request Dec 1, 2015
Merge pull request 28
@parkr parkr merged commit cecdefe into master Dec 1, 2015
@parkr parkr deleted the api branch December 1, 2015 18:25
parkr added a commit that referenced this pull request Dec 1, 2015
@jekyll jekyll locked and limited conversation to collaborators Feb 27, 2017
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants