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

Misc fixes for LibGit2 #18066

Merged
merged 5 commits into from
Aug 18, 2016
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
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
12 changes: 5 additions & 7 deletions base/libgit2/callbacks.jl
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ function authenticate_userpass(creds::UserPasswordCredentials, libgit2credptr::P
urlusername : username)
userpass = prompt("Password for '$schema$username@$host'", password=true)
end
(creds.user != username) || (creds.pass != userpass) && reset!(creds)
((creds.user != username) || (creds.pass != userpass)) && reset!(creds)
Copy link
Member Author

Choose a reason for hiding this comment

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

Fixes operator precedence issue. Mirrors 1d5a427

creds.user = username # save credentials
creds.pass = userpass # save credentials

Expand Down Expand Up @@ -209,12 +209,10 @@ function credentials_callback(libgit2credptr::Ptr{Ptr{Void}}, url_ptr::Cstring,
url = unsafe_string(url_ptr)

# parse url for schema and host
urlparts = match(urlmatcher, url)
schema = urlparts.captures[1]
urlusername = urlparts.captures[4]
urlusername = urlusername === nothing ? "" : String(urlusername)
host = urlparts.captures[5]
schema = schema === nothing ? "" : schema*"://"
urlparts = match(URL_REGEX, url)
schema = urlparts[:scheme] === nothing ? "" : urlparts[:scheme] * "://"
urlusername = urlparts[:user] === nothing ? "" : urlparts[:user]
host = urlparts[:host]

# get credentials object from payload pointer
@assert payload_ptr != C_NULL
Expand Down
8 changes: 7 additions & 1 deletion base/libgit2/utils.jl
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
# This file is a part of Julia. License is MIT: http://julialang.org/license

const urlmatcher = r"^(http[s]?|git|ssh)?(:\/\/)?((\w+)@)?([A-Za-z0-9\-\.]+)(:[0-9]+)?(.*)$"
const URL_REGEX = r"""
^(?:(?<scheme>https?|git|ssh)\:\/\/)?
(?:(?<user>.*?)(?:\:(?<password>.*?))?@)?
(?<host>[A-Za-z0-9\-\.]+)
(?:\:(?<port>\d+)?)?
(?<path>.*?)$
"""x
Copy link
Member Author

Choose a reason for hiding this comment

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

Fixes several things with the original regex including:

  • Doesn't fail or absorb password information into the username
  • SSH URLs would have the colon included in the path capture. e.g. "git@github.com:JuliaLang/Example.jl" would have the path ":JuliaLang/Example.jl"
  • Allows more complicated usernames including ones using hypens
  • Switched to using named groups for clarity


function version()
major = Ref{Cint}(0)
Expand Down
20 changes: 10 additions & 10 deletions test/libgit2-online.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,12 @@
#########
# init & clone
mktempdir() do dir
repo_url = "github.com/JuliaLang/Example.jl"
https_prefix = "https://"
ssh_prefix = "git@"
repo_url_https = "https://github.com/JuliaLang/Example.jl"
repo_url_git = "git@github.com:JuliaLang/Example.jl"
Copy link
Member Author

@omus omus Aug 16, 2016

Choose a reason for hiding this comment

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

Original code specified the SSH URL as git@github.com/JuliaLang/Example.jl instead of git@github.com:JuliaLang/Example.jl

#@testset "Cloning repository" begin
#@testset "with 'https' protocol" begin
repo_path = joinpath(dir, "Example1")
repo = LibGit2.clone(https_prefix*repo_url, repo_path)
repo = LibGit2.clone(repo_url_https, repo_path)
try
@test isdir(repo_path)
@test isdir(joinpath(repo_path, ".git"))
Expand All @@ -27,7 +26,7 @@ mktempdir() do dir
repo_path = joinpath(dir, "Example2")
# credentials are required because github tries to authenticate on unknown repo
cred = LibGit2.UserPasswordCredentials("","") # empty credentials cause authentication error
LibGit2.clone(https_prefix*repo_url*randstring(10), repo_path, payload=Nullable(cred))
LibGit2.clone(repo_url_https*randstring(10), repo_path, payload=Nullable(cred))
error("unexpected")
catch ex
@test isa(ex, LibGit2.Error.GitError)
Expand All @@ -37,12 +36,13 @@ mktempdir() do dir

#TODO: remove or condition on libgit2 features this test when ssh protocol will be supported
#@testset "with 'ssh' protocol (by default is not supported)" begin
repo_path = joinpath(dir, "Example3")
repo = LibGit2.clone(repo_url_git, repo_path)
try
repo_path = joinpath(dir, "Example3")
@test_throws LibGit2.Error.GitError LibGit2.clone(ssh_prefix*repo_url, repo_path)
catch ex
# but we cloned succesfully, so check that repo was created
ex.fail == 1 && @test isdir(joinpath(path, ".git"))
@test isdir(repo_path)
@test isdir(joinpath(repo_path, ".git"))
finally
finalize(repo)
Copy link
Member Author

Choose a reason for hiding this comment

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

Change to URL now makes the clone operation successful. Not sure if this test is still applicable

Copy link
Member

Choose a reason for hiding this comment

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

Well, the test used to fail that cloning via SSH failed, but it tested so incorrectly. I think leaving it is fine, or we could remove it entirely since SSH clone is tested in the regular libgit2 test.

Copy link
Member Author

Choose a reason for hiding this comment

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

Turns out the test was only successful on my local machine since I had SSH keys setup. I'll remove the test as in its current state it'll probably pass on machines with GitHub SSH keys but fail on everything else including the CI.

Copy link
Member

Choose a reason for hiding this comment

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

Sounds good. We do test SSH elsewhere.

end
#end
#end
Expand Down
33 changes: 33 additions & 0 deletions test/libgit2.jl
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,39 @@ const LIBGIT2_MIN_VER = v"0.23.0"
@test sig3.email == sig.email
#end

#@testset "URL parsing" begin
# Use all named group
m = match(LibGit2.URL_REGEX, "https://user:pass@hostname.com:80/path/repo.git")
@test m[:scheme] == "https"
@test m[:user] == "user"
@test m[:password] == "pass"
@test m[:host] == "hostname.com"
@test m[:port] == "80"
@test m[:path] == "/path/repo.git"

# Realistic example HTTP example
m = match(LibGit2.URL_REGEX, "https://github.com/JuliaLang/Example.jl.git")
@test m[:scheme] == "https"
@test m[:user] == nothing
@test m[:password] == nothing
@test m[:host] == "github.com"
@test m[:port] == nothing
@test m[:path] == "/JuliaLang/Example.jl.git"

# Realistic example SSH example
m = match(LibGit2.URL_REGEX, "git@github.com:JuliaLang/Example.jl.git")
@test m[:scheme] == nothing
@test m[:user] == "git"
@test m[:password] == nothing
@test m[:host] == "github.com"
@test m[:port] == nothing
@test m[:path] == "JuliaLang/Example.jl.git"

# Make sure that a username can contain special characters
m = match(LibGit2.URL_REGEX, "user-name@hostname.com")
@test m[:user] == "user-name"
#end

mktempdir() do dir
# test parameters
repo_url = "https://github.com/JuliaLang/Example.jl"
Expand Down