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

Commit 06bb8ce

Browse files
authored
Implement the Git REPL mode (#26)
1 parent 0e8a9fd commit 06bb8ce

File tree

6 files changed

+146
-6
lines changed

6 files changed

+146
-6
lines changed

Project.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,10 @@ version = "0.3.0-DEV"
55

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

910
[compat]
11+
ReplMaker = "0.2.3"
1012
julia = "1.3"
1113

1214
[extras]

README.md

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,28 @@ require at least Julia 1.3.
1616
GitCommand is intended to work on any platform that supports Julia,
1717
including (but not limited to) Windows, macOS, Linux, and FreeBSD.
1818

19-
# Examples
19+
## Examples
2020

2121
```julia
22-
using GitCommand
22+
julia> using GitCommand
2323

24-
git() do git
25-
run(`$git clone https://github.com/JuliaRegistries/General`)
26-
end
24+
julia> git() do git
25+
run(`$git clone https://github.com/JuliaRegistries/General`)
26+
end
2727
```
28+
29+
## Git REPL mode
30+
31+
```julia
32+
julia> using GitCommand
33+
34+
julia> gitrepl() # you only need to run this once per Julia session
35+
36+
# Press , to enter the Git REPL mode
37+
38+
git> clone https://github.com/JuliaRegistries/General
39+
```
40+
41+
## Acknowledgements
42+
43+
- 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.

src/GitCommand.jl

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,19 @@
11
module GitCommand
22

33
import Git_jll
4+
import ReplMaker
45

5-
export git
66
# export @git_cmd
7+
export git
8+
export gitrepl
9+
10+
const GIT_REPL_MODE_NAME = "GitCommand.jl Git REPL mode"
11+
const GIT_REPL_MODE_PROMPT_TEXT = "git> "
12+
const GIT_REPL_MODE_START_KEY = ','
713

814
include("env_mapping.jl")
915
include("git_cmd.jl")
16+
include("git_repl.jl")
1017
include("nonpublic.jl")
1118
include("public.jl")
1219
include("util.jl")

src/git_repl.jl

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import ReplMaker
2+
3+
function _gitrepl(; mode_name = GIT_REPL_MODE_NAME,
4+
prompt_text = GIT_REPL_MODE_PROMPT_TEXT,
5+
start_key = GIT_REPL_MODE_START_KEY,
6+
kwargs...)
7+
return ReplMaker.initrepl(_gitrepl_parser;
8+
mode_name = mode_name,
9+
prompt_text = prompt_text,
10+
start_key = start_key,
11+
kwargs...)
12+
end
13+
14+
function _gitrepl_parser(repl_input::AbstractString)
15+
return quote
16+
GitCommand.git() do git
17+
repl_input = $(Expr(:quote, repl_input))
18+
run(`$(git) $(split(repl_input))`)
19+
return nothing
20+
end
21+
end
22+
end

src/public.jl

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,14 @@ function git(f::Function;
77
return f(git_path)
88
end
99
end
10+
11+
function gitrepl(; mode_name = GIT_REPL_MODE_NAME,
12+
prompt_text = GIT_REPL_MODE_PROMPT_TEXT,
13+
start_key = GIT_REPL_MODE_START_KEY,
14+
kwargs...)::Nothing
15+
_gitrepl(; mode_name = mode_name,
16+
prompt_text = prompt_text,
17+
start_key = start_key,
18+
kwargs...)
19+
return nothing
20+
end

test/runtests.jl

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,48 @@
11
using GitCommand
22
using Test
33

4+
# Some of the code in this file is based on:
5+
# https://github.com/MasonProtter/ReplMaker.jl/blob/master/test/runtests.jl
6+
7+
Base.include(@__MODULE__, joinpath(Sys.BINDIR, "..", "share", "julia", "test", "testhelpers", "FakePTYs.jl"))
8+
import .FakePTYs
9+
10+
const CTRL_C = '\x03'
11+
12+
function run_repl_test(test_script)
13+
slave, master = FakePTYs.open_fake_pty()
14+
# Start a julia process
15+
p = run(`$(Base.julia_cmd()) --code-coverage=user --history-file=no --startup-file=no --compiled-modules=no`, slave, slave, slave; wait=false)
16+
17+
# Read until the prompt
18+
readuntil(master, "julia>", keep=true)
19+
done = false
20+
repl_output_buffer = IOBuffer()
21+
22+
# A task that just keeps reading the output
23+
@async begin
24+
while true
25+
done && break
26+
write(repl_output_buffer, readavailable(master))
27+
end
28+
end
29+
30+
# Execute our "script"
31+
for l in split(test_script, '\n'; keepempty=false)
32+
write(master, l, '\n')
33+
end
34+
35+
# Let the REPL exit
36+
write(master, "exit()\n")
37+
wait(p)
38+
done = true
39+
40+
# Gather the output
41+
repl_output = String(take!(repl_output_buffer))
42+
println(repl_output)
43+
return split(repl_output, '\n'; keepempty=false)
44+
end
45+
446
function with_temp_dir(f::Function)
547
original_directory = pwd()
648
tmp_dir = mktempdir()
@@ -18,22 +60,62 @@ end
1860
else
1961
@test GitCommand._separator() == ':'
2062
end
63+
2164
with_temp_dir() do tmp_dir
2265
@test !isdir("General")
2366
@test !isfile(joinpath("General", "Registry.toml"))
2467
git() do git
68+
@test !isdir("General")
69+
@test !isfile(joinpath("General", "Registry.toml"))
2570
run(`$git clone https://github.com/JuliaRegistries/General`)
2671
end
2772
@test isdir("General")
2873
@test isfile(joinpath("General", "Registry.toml"))
2974
end
75+
3076
with_temp_dir() do tmp_dir
3177
@test !isdir("General")
3278
@test !isfile(joinpath("General", "Registry.toml"))
3379
cmd = GitCommand.git`clone https://github.com/JuliaRegistries/General`
3480
@test cmd isa Cmd
81+
@test !isdir("General")
82+
@test !isfile(joinpath("General", "Registry.toml"))
3583
run(cmd)
3684
@test isdir("General")
3785
@test isfile(joinpath("General", "Registry.toml"))
3886
end
87+
88+
with_temp_dir() do tmp_dir
89+
@test !isdir("General")
90+
@test !isfile(joinpath("General", "Registry.toml"))
91+
expr = GitCommand._gitrepl_parser("clone https://github.com/JuliaRegistries/General")
92+
@test expr isa Expr
93+
@test !isdir("General")
94+
@test !isfile(joinpath("General", "Registry.toml"))
95+
@eval $(expr)
96+
@test isdir("General")
97+
@test isfile(joinpath("General", "Registry.toml"))
98+
end
99+
100+
with_temp_dir() do tmp_dir
101+
withenv("JULIA_DEBUG" => "all") do
102+
@test_throws UndefVarError gitrepl()
103+
end
104+
end
105+
106+
with_temp_dir() do tmp_dir
107+
repl_test_script_1 = """
108+
import GitCommand
109+
GitCommand.gitrepl()
110+
,clone https://github.com/JuliaRegistries/General
111+
"""*CTRL_C
112+
@test !isdir("General")
113+
@test !isfile(joinpath("General", "Registry.toml"))
114+
if Sys.iswindows()
115+
else
116+
run_repl_test(repl_test_script_1)
117+
@test isdir("General")
118+
@test isfile(joinpath("General", "Registry.toml"))
119+
end
120+
end
39121
end

0 commit comments

Comments
 (0)