From 096a652874d0481a3e7b8f20ceb0290664126055 Mon Sep 17 00:00:00 2001 From: Kristoffer Carlsson Date: Wed, 27 Jun 2018 17:10:30 +0200 Subject: [PATCH] add setprotocol! to new package manager (#430) --- stdlib/Pkg/src/API.jl | 8 ++++++++ stdlib/Pkg/src/GitTools.jl | 24 ++++++++++++++++++++++-- stdlib/Pkg/src/Pkg.jl | 37 +++++++++++++++++++------------------ stdlib/Pkg/src/Types.jl | 7 +------ stdlib/Pkg/test/pkg.jl | 17 +++++++++++++++++ 5 files changed, 67 insertions(+), 26 deletions(-) diff --git a/stdlib/Pkg/src/API.jl b/stdlib/Pkg/src/API.jl index 69728f0c8810e..ab01f916f895a 100644 --- a/stdlib/Pkg/src/API.jl +++ b/stdlib/Pkg/src/API.jl @@ -560,4 +560,12 @@ function activate(path::Union{String,Nothing}=nothing) Base.ACTIVE_PROJECT[] = Base.load_path_expand(path) end +""" + setprotocol!(proto::Union{Nothing, AbstractString}=nothing) + +Set the protocol used to access GitHub-hosted packages when `add`ing a url or `develop`ing a package. +Defaults to 'https', with `proto == nothing` delegating the choice to the package developer. +""" +setprotocol!(proto::Union{Nothing, AbstractString}=nothing) = GitTools.setprotocol!(proto) + end # module diff --git a/stdlib/Pkg/src/GitTools.jl b/stdlib/Pkg/src/GitTools.jl index 194d9176d49a5..7daaf41ee2400 100644 --- a/stdlib/Pkg/src/GitTools.jl +++ b/stdlib/Pkg/src/GitTools.jl @@ -65,6 +65,20 @@ function transfer_progress(progress::Ptr{LibGit2.TransferProgress}, p::Any) return Cint(0) end + +const GITHUB_REGEX = + r"^(?:git@|git://|https://(?:[\w\.\+\-]+@)?)github.com[:/](([^/].+)/(.+?))(?:\.git)?$"i +const GIT_PROTOCOL = Ref{Union{String, Nothing}}("https") + +setprotocol!(proto::Union{Nothing, AbstractString}=nothing) = GIT_PROTOCOL[] = proto + +# TODO: extend this to more urls +function normalize_url(url::AbstractString) + m = match(GITHUB_REGEX, url) + (m === nothing || GIT_PROTOCOL[] === nothing) ? + url : "$(GIT_PROTOCOL[])://github.com/$(m.captures[1]).git" +end + function clone(url, source_path; header=nothing, kwargs...) Pkg.Types.printpkgstyle(stdout, :Cloning, header == nothing ? "git-repo `$url`" : header) transfer_payload = MiniProgressBar(header = "Fetching:", color = Base.info_color()) @@ -74,12 +88,14 @@ function clone(url, source_path; header=nothing, kwargs...) transfer_payload, ) ) + url = normalize_url(url) print(stdout, "\e[?25l") # disable cursor try return LibGit2.clone(url, source_path; callbacks=callbacks, kwargs...) - catch e + catch err rm(source_path; force=true, recursive=true) - rethrow(e) + err isa LibGit2.GitError || rethrow(err) + Pkg.Typs.cmderror("failed to clone from $(url), error: $err") finally print(stdout, "\033[2K") # clear line print(stdout, "\e[?25h") # put back cursor @@ -92,6 +108,7 @@ function fetch(repo::LibGit2.GitRepo, remoteurl=nothing; header=nothing, kwargs. LibGit2.url(remote) end end + remoteurl = normalize_url(remoteurl) Pkg.Types.printpkgstyle(stdout, :Updating, header == nothing ? "git-repo `$remoteurl`" : header) transfer_payload = MiniProgressBar(header = "Fetching:", color = Base.info_color()) callbacks = LibGit2.Callbacks( @@ -103,6 +120,9 @@ function fetch(repo::LibGit2.GitRepo, remoteurl=nothing; header=nothing, kwargs. print(stdout, "\e[?25l") # disable cursor try return LibGit2.fetch(repo; remoteurl=remoteurl, callbacks=callbacks, kwargs...) + catch err + err isa LibGit2.GitError || rethrow(err) + Pkg.Types.cmderror("failed to fetch from $(remoteurl), error: $err") finally print(stdout, "\033[2K") # clear line print(stdout, "\e[?25h") # put back cursor diff --git a/stdlib/Pkg/src/Pkg.jl b/stdlib/Pkg/src/Pkg.jl index ec76770ea2f33..910e3838cb0ba 100644 --- a/stdlib/Pkg/src/Pkg.jl +++ b/stdlib/Pkg/src/Pkg.jl @@ -27,24 +27,25 @@ include("API.jl") include("REPLMode.jl") # Define new variables so tab comleting Pkg. works. -const add = API.add -const rm = API.rm -const up = API.up -const test = API.test -const gc = API.gc -const init = API.init -const build = API.build -const installed = API.installed -const pin = API.pin -const free = API.free -const checkout = API.checkout -const develop = API.develop -const generate = API.generate -const instantiate = API.instantiate -const resolve = API.resolve -const status = Display.status -const update = up -const activate = API.activate +const add = API.add +const rm = API.rm +const up = API.up +const test = API.test +const gc = API.gc +const init = API.init +const build = API.build +const installed = API.installed +const pin = API.pin +const free = API.free +const checkout = API.checkout +const develop = API.develop +const generate = API.generate +const instantiate = API.instantiate +const resolve = API.resolve +const status = Display.status +const update = up +const activate = API.activate +const setprotocol! = API.setprotocol! # legacy CI script support import .API: clone, dir diff --git a/stdlib/Pkg/src/Types.jl b/stdlib/Pkg/src/Types.jl index 92c19b8df22be..62eab39c78096 100644 --- a/stdlib/Pkg/src/Types.jl +++ b/stdlib/Pkg/src/Types.jl @@ -498,12 +498,7 @@ function handle_repos_add!(ctx::Context, pkgs::AbstractVector{PackageSpec}; upgr pinned = (info != nothing && get(info, "pinned", false)) if upgrade_or_add && !pinned && !just_cloned rev = pkg.repo.rev - try - GitTools.fetch(repo, pkg.repo.url; refspecs=refspecs, credentials=creds) - catch e - e isa LibGit2.GitError || rethrow(e) - cmderror("failed to fetch from $(pkg.repo.url), error: $e") - end + GitTools.fetch(repo, pkg.repo.url; refspecs=refspecs, credentials=creds) end if upgrade_or_add && !pinned rev = pkg.repo.rev diff --git a/stdlib/Pkg/test/pkg.jl b/stdlib/Pkg/test/pkg.jl index 1702349fab29d..3ffb04b4cd383 100644 --- a/stdlib/Pkg/test/pkg.jl +++ b/stdlib/Pkg/test/pkg.jl @@ -201,6 +201,23 @@ temp_pkg_dir() do project_path end end + @testset "protocols" begin + mktempdir() do devdir + withenv("JULIA_PKG_DEVDIR" => devdir) do + try + Pkg.setprotocol!("notarealprotocol") + # Pkg.develop is broken, update to use when fixed + @test_throws CommandError pkg"develop Example" + Pkg.setprotocol!() + pkg"develop Example" + @test isinstalled(TEST_PKG) + finally + Pkg.setprotocol!() + end + end + end + end + @testset "check logging" begin usage = Pkg.TOML.parse(String(read(joinpath(Pkg.logdir(), "manifest_usage.toml")))) @test any(x -> startswith(x, joinpath(project_path, "Manifest.toml")), keys(usage))