diff --git a/base/libgit2/callbacks.jl b/base/libgit2/callbacks.jl index fd2580da27ee7..13f2f88e168de 100644 --- a/base/libgit2/callbacks.jl +++ b/base/libgit2/callbacks.jl @@ -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) creds.user = username # save credentials creds.pass = userpass # save credentials @@ -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 diff --git a/base/libgit2/utils.jl b/base/libgit2/utils.jl index ba2149dbda576..ab8928687e3c7 100644 --- a/base/libgit2/utils.jl +++ b/base/libgit2/utils.jl @@ -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""" +^(?:(?https?|git|ssh)\:\/\/)? +(?:(?.*?)(?:\:(?.*?))?@)? +(?[A-Za-z0-9\-\.]+) +(?:\:(?\d+)?)? +(?.*?)$ +"""x function version() major = Ref{Cint}(0) diff --git a/test/libgit2-online.jl b/test/libgit2-online.jl index 436003eb37160..dd02d6c42d37f 100644 --- a/test/libgit2-online.jl +++ b/test/libgit2-online.jl @@ -7,13 +7,11 @@ ######### # init & clone mktempdir() do dir - repo_url = "github.com/JuliaLang/Example.jl" - https_prefix = "https://" - ssh_prefix = "git@" + repo_url = "https://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, repo_path) try @test isdir(repo_path) @test isdir(joinpath(repo_path, ".git")) @@ -27,24 +25,13 @@ 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*randstring(10), repo_path, payload=Nullable(cred)) error("unexpected") catch ex @test isa(ex, LibGit2.Error.GitError) @test ex.code == LibGit2.Error.EAUTH end #end - - #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 - 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")) - end - #end #end end diff --git a/test/libgit2.jl b/test/libgit2.jl index a0466c21c7e15..d2a8fbc91b48d 100644 --- a/test/libgit2.jl +++ b/test/libgit2.jl @@ -76,10 +76,60 @@ const LIBGIT2_MIN_VER = v"0.23.0" @test sig3.email == sig.email #end +#@testset "URL parsing" begin + # HTTPS URL + m = match(LibGit2.URL_REGEX, "https://user:pass@server.com:80/org/project.git") + @test m[:scheme] == "https" + @test m[:user] == "user" + @test m[:password] == "pass" + @test m[:host] == "server.com" + @test m[:port] == "80" + @test m[:path] == "/org/project.git" + + # SSH URL + m = match(LibGit2.URL_REGEX, "ssh://user:pass@server:22/project.git") + @test m[:scheme] == "ssh" + @test m[:user] == "user" + @test m[:password] == "pass" + @test m[:host] == "server" + @test m[:port] == "22" + @test m[:path] == "/project.git" + + # SSH URL using scp-like syntax + m = match(LibGit2.URL_REGEX, "user@server:project.git") + @test m[:scheme] == nothing + @test m[:user] == "user" + @test m[:password] == nothing + @test m[:host] == "server" + @test m[:port] == nothing + @test m[:path] == "project.git" + + # Realistic example from GitHub using HTTPS + 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 from GitHub using SSH + 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 usernames 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" - ssh_prefix = "git@" cache_repo = joinpath(dir, "Example") test_repo = joinpath(dir, "Example.Test") test_sig = LibGit2.Signature("TEST", "TEST@TEST.COM", round(time(), 0), 0)