Skip to content
This repository has been archived by the owner on Mar 26, 2021. It is now read-only.

Implement the Git REPL mode #26

Merged
merged 2 commits into from Dec 18, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions Project.toml
Expand Up @@ -5,8 +5,10 @@ version = "0.3.0-DEV"

[deps]
Git_jll = "f8c6e375-362e-5223-8a59-34ff63f689eb"
ReplMaker = "b873ce64-0db9-51f5-a568-4457d8e49576"

[compat]
DilumAluthge marked this conversation as resolved.
Show resolved Hide resolved
ReplMaker = "0.2.3"
julia = "1.3"

[extras]
Expand Down
26 changes: 21 additions & 5 deletions README.md
Expand Up @@ -16,12 +16,28 @@ require at least Julia 1.3.
GitCommand is intended to work on any platform that supports Julia,
including (but not limited to) Windows, macOS, Linux, and FreeBSD.

# Examples
## Examples

```julia
using GitCommand
julia> using GitCommand

git() do git
run(`$git clone https://github.com/JuliaRegistries/General`)
end
julia> git() do git
run(`$git clone https://github.com/JuliaRegistries/General`)
end
```

## Git REPL mode

```julia
julia> using GitCommand

julia> gitrepl() # you only need to run this once per Julia session

# Press , to enter the Git REPL mode

git> clone https://github.com/JuliaRegistries/General
```

## Acknowledgements

- This work was supported in part by National Institutes of Health grants U54GM115677, R01LM011963, and R25MH116440. The content is solely the responsibility of the authors and does not necessarily represent the official views of the National Institutes of Health.
9 changes: 8 additions & 1 deletion src/GitCommand.jl
@@ -1,12 +1,19 @@
module GitCommand

import Git_jll
import ReplMaker

export git
# export @git_cmd
export git
export gitrepl

const GIT_REPL_MODE_NAME = "GitCommand.jl Git REPL mode"
const GIT_REPL_MODE_PROMPT_TEXT = "git> "
const GIT_REPL_MODE_START_KEY = ','

include("env_mapping.jl")
include("git_cmd.jl")
include("git_repl.jl")
include("nonpublic.jl")
include("public.jl")
include("util.jl")
Expand Down
22 changes: 22 additions & 0 deletions src/git_repl.jl
@@ -0,0 +1,22 @@
import ReplMaker

function _gitrepl(; mode_name = GIT_REPL_MODE_NAME,
prompt_text = GIT_REPL_MODE_PROMPT_TEXT,
start_key = GIT_REPL_MODE_START_KEY,
kwargs...)
return ReplMaker.initrepl(_gitrepl_parser;
mode_name = mode_name,
prompt_text = prompt_text,
start_key = start_key,
kwargs...)
end

function _gitrepl_parser(repl_input::AbstractString)
return quote
GitCommand.git() do git
repl_input = $(Expr(:quote, repl_input))
run(`$(git) $(split(repl_input))`)
return nothing
end
end
end
11 changes: 11 additions & 0 deletions src/public.jl
Expand Up @@ -7,3 +7,14 @@ function git(f::Function;
return f(git_path)
end
end

function gitrepl(; mode_name = GIT_REPL_MODE_NAME,
prompt_text = GIT_REPL_MODE_PROMPT_TEXT,
start_key = GIT_REPL_MODE_START_KEY,
kwargs...)::Nothing
_gitrepl(; mode_name = mode_name,
prompt_text = prompt_text,
start_key = start_key,
kwargs...)
return nothing
end
82 changes: 82 additions & 0 deletions test/runtests.jl
@@ -1,6 +1,48 @@
using GitCommand
using Test

# Some of the code in this file is based on:
# https://github.com/MasonProtter/ReplMaker.jl/blob/master/test/runtests.jl

Base.include(@__MODULE__, joinpath(Sys.BINDIR, "..", "share", "julia", "test", "testhelpers", "FakePTYs.jl"))
import .FakePTYs

const CTRL_C = '\x03'

function run_repl_test(test_script)
slave, master = FakePTYs.open_fake_pty()
# Start a julia process
p = run(`$(Base.julia_cmd()) --code-coverage=user --history-file=no --startup-file=no --compiled-modules=no`, slave, slave, slave; wait=false)

# Read until the prompt
readuntil(master, "julia>", keep=true)
done = false
repl_output_buffer = IOBuffer()

# A task that just keeps reading the output
@async begin
while true
done && break
write(repl_output_buffer, readavailable(master))
end
end

# Execute our "script"
for l in split(test_script, '\n'; keepempty=false)
write(master, l, '\n')
end

# Let the REPL exit
write(master, "exit()\n")
wait(p)
done = true

# Gather the output
repl_output = String(take!(repl_output_buffer))
println(repl_output)
return split(repl_output, '\n'; keepempty=false)
end

function with_temp_dir(f::Function)
original_directory = pwd()
tmp_dir = mktempdir()
Expand All @@ -18,22 +60,62 @@ end
else
@test GitCommand._separator() == ':'
end

with_temp_dir() do tmp_dir
@test !isdir("General")
@test !isfile(joinpath("General", "Registry.toml"))
git() do git
@test !isdir("General")
@test !isfile(joinpath("General", "Registry.toml"))
run(`$git clone https://github.com/JuliaRegistries/General`)
end
@test isdir("General")
@test isfile(joinpath("General", "Registry.toml"))
end

with_temp_dir() do tmp_dir
@test !isdir("General")
@test !isfile(joinpath("General", "Registry.toml"))
cmd = GitCommand.git`clone https://github.com/JuliaRegistries/General`
@test cmd isa Cmd
@test !isdir("General")
@test !isfile(joinpath("General", "Registry.toml"))
run(cmd)
@test isdir("General")
@test isfile(joinpath("General", "Registry.toml"))
end

with_temp_dir() do tmp_dir
@test !isdir("General")
@test !isfile(joinpath("General", "Registry.toml"))
expr = GitCommand._gitrepl_parser("clone https://github.com/JuliaRegistries/General")
@test expr isa Expr
@test !isdir("General")
@test !isfile(joinpath("General", "Registry.toml"))
@eval $(expr)
@test isdir("General")
@test isfile(joinpath("General", "Registry.toml"))
end

with_temp_dir() do tmp_dir
withenv("JULIA_DEBUG" => "all") do
@test_throws UndefVarError gitrepl()
end
end

with_temp_dir() do tmp_dir
repl_test_script_1 = """
import GitCommand
GitCommand.gitrepl()
,clone https://github.com/JuliaRegistries/General
"""*CTRL_C
@test !isdir("General")
@test !isfile(joinpath("General", "Registry.toml"))
if Sys.iswindows()
else
run_repl_test(repl_test_script_1)
@test isdir("General")
@test isfile(joinpath("General", "Registry.toml"))
end
end
end