This repository has been archived by the owner on May 16, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 15
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Refactor GitHub impl and add GH Enterprise support
- Loading branch information
1 parent
61ae182
commit 8e6dcab
Showing
9 changed files
with
237 additions
and
106 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
require "chandler/github/errors" | ||
require "delegate" | ||
require "octokit" | ||
require "uri" | ||
|
||
module Chandler | ||
class GitHub | ||
# A thin wrapper around Octokit::Client that adds support for automatic | ||
# GitHub Enterprise, .netrc, and ENV token-based authentication. | ||
# | ||
class Client < SimpleDelegator | ||
def initialize(host: "github.com", | ||
environment: ENV, | ||
octokit_client: Octokit::Client) | ||
super(octokit_client.new(detect_auth_option(environment))) | ||
assign_enterprise_endpoint(host) | ||
end | ||
|
||
def login! | ||
return if login | ||
raise netrc ? NetrcAuthenticationFailure : TokenAuthenticationFailure | ||
end | ||
|
||
private | ||
|
||
def detect_auth_option(env) | ||
if (token = env["CHANDLER_GITHUB_API_TOKEN"]) | ||
{ :access_token => token } | ||
else | ||
{ :netrc => true } | ||
end | ||
end | ||
|
||
def assign_enterprise_endpoint(host) | ||
return if host.downcase == "github.com" | ||
self.api_endpoint = "https://#{host}/api/v3/" | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
require "uri" | ||
|
||
module Chandler | ||
class GitHub | ||
# Assuming a git remote points to a public GitHub or a GitHub Enterprise | ||
# repository, this class parses the remote to obtain the host and repository | ||
# path. Supports SSH and HTTPS style git remotes. | ||
# | ||
# This class also handles parsing values passed into the `--github` command | ||
# line option, which may be a public GitHub repository name, like | ||
# "mattbrictson/chandler". | ||
# | ||
class Remote | ||
def self.parse(url) | ||
if (match = url.match(/@([^:]+):(.+)$/)) | ||
new(match[1], match[2]) | ||
else | ||
parsed_uri = URI(url) | ||
host = parsed_uri.host || "github.com" | ||
path = parsed_uri.path.sub(%r{^/+}, "") | ||
new(host, path) | ||
end | ||
end | ||
|
||
attr_reader :host, :path | ||
|
||
def initialize(host, path) | ||
@host = host.downcase | ||
@path = path | ||
end | ||
|
||
def repository | ||
path.sub(/\.git$/, "") | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
require "minitest_helper" | ||
require "chandler/github/client" | ||
|
||
class Chandler::GitHub::ClientTest < Minitest::Test | ||
class FakeOctokitClient | ||
attr_reader :netrc, :access_token | ||
attr_accessor :api_endpoint | ||
|
||
def initialize(auth_options) | ||
@netrc = auth_options.fetch(:netrc, false) | ||
@access_token = auth_options[:access_token] | ||
end | ||
|
||
def login | ||
"successful" | ||
end | ||
end | ||
|
||
class FakeOctokitClientWithError < FakeOctokitClient | ||
def login | ||
nil | ||
end | ||
end | ||
|
||
def test_uses_netrc_by_default | ||
client = Chandler::GitHub::Client.new(:octokit_client => FakeOctokitClient) | ||
assert(client.netrc) | ||
assert_nil(client.access_token) | ||
end | ||
|
||
def test_uses_access_token_from_env | ||
client = Chandler::GitHub::Client.new( | ||
:environment => { "CHANDLER_GITHUB_API_TOKEN" => "foo" }, | ||
:octokit_client => FakeOctokitClient | ||
) | ||
assert_equal("foo", client.access_token) | ||
refute(client.netrc) | ||
end | ||
|
||
def test_doesnt_change_default_endpoint_for_public_github | ||
client = Chandler::GitHub::Client.new( | ||
:host => "github.com", | ||
:octokit_client => FakeOctokitClient | ||
) | ||
assert_nil(client.api_endpoint) | ||
end | ||
|
||
def test_assigns_enterprise_endpoint | ||
client = Chandler::GitHub::Client.new( | ||
:host => "github.example.com", | ||
:octokit_client => FakeOctokitClient | ||
) | ||
assert_equal("https://github.example.com/api/v3/", client.api_endpoint) | ||
end | ||
|
||
def test_raises_exception_if_netrc_fails | ||
assert_raises(Chandler::GitHub::NetrcAuthenticationFailure) do | ||
Chandler::GitHub::Client.new( | ||
:octokit_client => FakeOctokitClientWithError | ||
).login! | ||
end | ||
end | ||
|
||
def test_raises_exception_if_access_token_fails | ||
assert_raises(Chandler::GitHub::TokenAuthenticationFailure) do | ||
Chandler::GitHub::Client.new( | ||
:environment => { "CHANDLER_GITHUB_API_TOKEN" => "foo" }, | ||
:octokit_client => FakeOctokitClientWithError | ||
).login! | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
require "minitest_helper" | ||
require "chandler/github/remote" | ||
|
||
class Chandler::GitHub::RemoteTest < Minitest::Test | ||
def test_bare_repository_name | ||
repo = parse("mattbrictson/chandler") | ||
assert_equal("github.com", repo.host) | ||
assert_equal("mattbrictson/chandler", repo.repository) | ||
end | ||
|
||
def test_ssh_style_url | ||
repo = parse("git@github.com:mattbrictson/chandler.git") | ||
assert_equal("github.com", repo.host) | ||
assert_equal("mattbrictson/chandler", repo.repository) | ||
end | ||
|
||
def test_https_url | ||
repo = parse("https://github.com/mattbrictson/chandler.git") | ||
assert_equal("github.com", repo.host) | ||
assert_equal("mattbrictson/chandler", repo.repository) | ||
end | ||
|
||
def test_enterprise_ssh_style_url | ||
repo = parse("git@github.example.com:org/project.git") | ||
assert_equal("github.example.com", repo.host) | ||
assert_equal("org/project", repo.repository) | ||
end | ||
|
||
private | ||
|
||
def parse(url) | ||
Chandler::GitHub::Remote.parse(url) | ||
end | ||
end |
Oops, something went wrong.