gitXplorer 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/bin/gitX +137 -0
- data/bin/gitXplorer +137 -0
- data/bin/gitx +137 -0
- data/bin/gitxplorer +137 -0
- data/lib/git_xplorer/error/invalid_revision.rb +5 -0
- data/lib/git_xplorer/error/no_chaining_allowed.rb +5 -0
- data/lib/git_xplorer/error/no_file_or_directory.rb +5 -0
- data/lib/git_xplorer/error/no_semicolons_allowed.rb +5 -0
- data/lib/git_xplorer/error/no_subshells_allowed.rb +5 -0
- data/lib/git_xplorer/error/not_directory.rb +5 -0
- data/lib/git_xplorer/error/not_file.rb +5 -0
- data/lib/git_xplorer/error.rb +10 -0
- data/lib/git_xplorer/git_object/directory.rb +67 -0
- data/lib/git_xplorer/git_object/file.rb +48 -0
- data/lib/git_xplorer/git_object/revision.rb +21 -0
- data/lib/git_xplorer/git_object.rb +112 -0
- data/lib/git_xplorer/wish/cat_wish.rb +40 -0
- data/lib/git_xplorer/wish/change_directory_wish.rb +44 -0
- data/lib/git_xplorer/wish/find_wish.rb +28 -0
- data/lib/git_xplorer/wish/git_wish.rb +30 -0
- data/lib/git_xplorer/wish/grep_wish.rb +45 -0
- data/lib/git_xplorer/wish/list_directory_wish.rb +93 -0
- data/lib/git_xplorer/wish/pwd_wish.rb +24 -0
- data/lib/git_xplorer/wish/vi_wish.rb +46 -0
- data/lib/git_xplorer.rb +219 -0
- metadata +152 -0
data/lib/git_xplorer.rb
ADDED
@@ -0,0 +1,219 @@
|
|
1
|
+
require "hilighter"
|
2
|
+
require "scoobydoo"
|
3
|
+
|
4
|
+
class GitXplorer
|
5
|
+
def absolute_path(path = nil)
|
6
|
+
path ||= ""
|
7
|
+
return "#{@cwd.join("/")}#{"/" if (!@cwd.empty?)}#{path}"
|
8
|
+
end
|
9
|
+
private :absolute_path
|
10
|
+
|
11
|
+
def cd(path = nil)
|
12
|
+
path ||= ""
|
13
|
+
|
14
|
+
# No path means go to top-level
|
15
|
+
@cwd.clear if (path.empty?)
|
16
|
+
|
17
|
+
target = @tree.get(absolute_path(path))
|
18
|
+
if (target.nil?)
|
19
|
+
raise GitXplorer::Error::NoFileOrDirectory.new(path)
|
20
|
+
elsif (!target.is_a?(GitXplorer::GitObject::Directory))
|
21
|
+
raise GitXplorer::Error::NotDirectory.new(path)
|
22
|
+
end
|
23
|
+
|
24
|
+
path.split("/"). each do |dir|
|
25
|
+
case dir
|
26
|
+
when "."
|
27
|
+
# Do nothing
|
28
|
+
when ".."
|
29
|
+
@cwd.delete_at(-1)
|
30
|
+
else
|
31
|
+
@cwd.push(dir)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
# Return the target
|
36
|
+
return target
|
37
|
+
end
|
38
|
+
|
39
|
+
def exist?(path)
|
40
|
+
return @tree.exist?(absolute_path(path))
|
41
|
+
end
|
42
|
+
|
43
|
+
def get_completions(input)
|
44
|
+
return @tree.get_completions(absolute_path(input))
|
45
|
+
end
|
46
|
+
|
47
|
+
def get_filenames(dir = "", pattern = ".")
|
48
|
+
dir ||= ""
|
49
|
+
pattern ||= "."
|
50
|
+
|
51
|
+
found = %x(
|
52
|
+
git log --diff-filter=ACR --name-only --pretty=tformat: \
|
53
|
+
-- #{dir}
|
54
|
+
).split("\n").map do |file|
|
55
|
+
file.gsub(/^#{dir}/, "")
|
56
|
+
end.select do |file|
|
57
|
+
file.match(/#{pattern}/)
|
58
|
+
end
|
59
|
+
|
60
|
+
return found
|
61
|
+
end
|
62
|
+
|
63
|
+
def git(args, refresh = true)
|
64
|
+
if (args.match(/.*;.*/))
|
65
|
+
raise GitXplorer::Error::NoSemicolonsAllowed.new
|
66
|
+
end
|
67
|
+
|
68
|
+
if (args.match(/(\$|<)\(.+\)/))
|
69
|
+
raise GitXplorer::Error::NoSubshellsAllowed.new
|
70
|
+
end
|
71
|
+
|
72
|
+
if (args.match(/\&\&|\|\|/))
|
73
|
+
raise GitXplorer::Error::NoChainingAllowed.new
|
74
|
+
end
|
75
|
+
|
76
|
+
out = %x(git #{args})
|
77
|
+
refresh = true if (refresh.nil?)
|
78
|
+
@tree = refresh_tree if (refresh)
|
79
|
+
return out
|
80
|
+
end
|
81
|
+
|
82
|
+
def initialize
|
83
|
+
@cwd = Array.new
|
84
|
+
@repo = %x(git rev-parse --show-toplevel).split("/")[-1].strip
|
85
|
+
@tree = refresh_tree
|
86
|
+
end
|
87
|
+
|
88
|
+
def ls(path = nil)
|
89
|
+
path = absolute_path(path)
|
90
|
+
|
91
|
+
# Get target directory if it exists
|
92
|
+
target = @tree.get(path)
|
93
|
+
if (target.nil?)
|
94
|
+
raise GitXplorer::Error::NoFileOrDirectory.new(path)
|
95
|
+
end
|
96
|
+
|
97
|
+
return target.children
|
98
|
+
end
|
99
|
+
|
100
|
+
def pwd
|
101
|
+
# Return repo name if at top-level
|
102
|
+
return @repo if (@cwd.empty?)
|
103
|
+
|
104
|
+
# Return repo name followed by CWD
|
105
|
+
return "#{@repo}/#{@cwd.join("/")}#{"/" if (!@cwd.empty?)}"
|
106
|
+
end
|
107
|
+
|
108
|
+
def pwd_short
|
109
|
+
# Return repo name if at top-level
|
110
|
+
return @repo if (@cwd.empty?)
|
111
|
+
|
112
|
+
# Return only the last 3 directories if more than 3 deep
|
113
|
+
return @cwd[-3..-1].join("/") if (@cwd.length >= 3)
|
114
|
+
|
115
|
+
# Return repo name followed by CWD
|
116
|
+
return "#{@repo}/#{@cwd.join("/")}#{"/" if (!@cwd.empty?)}"
|
117
|
+
end
|
118
|
+
|
119
|
+
def refresh_tree
|
120
|
+
# Create tree root
|
121
|
+
tree = GitXplorer::GitObject::Directory.new("/", nil)
|
122
|
+
|
123
|
+
# Add files to tree
|
124
|
+
get_filenames.sort do |a, b|
|
125
|
+
a.downcase <=> b.downcase
|
126
|
+
end.each do |path|
|
127
|
+
tree.add(path)
|
128
|
+
end
|
129
|
+
|
130
|
+
# Return the tree
|
131
|
+
return tree
|
132
|
+
end
|
133
|
+
private :refresh_tree
|
134
|
+
|
135
|
+
def search(dir = "", pattern = ".")
|
136
|
+
dir ||= ""
|
137
|
+
pattern ||= "."
|
138
|
+
|
139
|
+
found = %x(
|
140
|
+
git grep -HIinP "#{pattern}" $(git rev-list --all) -- \
|
141
|
+
#{dir}
|
142
|
+
).split("\n").map do |line|
|
143
|
+
line.gsub(
|
144
|
+
/^([^:]+):([^:]+):(\d+):(.*)$/,
|
145
|
+
"\\2:\\1:\\3:\\4"
|
146
|
+
)
|
147
|
+
end
|
148
|
+
|
149
|
+
return found
|
150
|
+
end
|
151
|
+
|
152
|
+
def show(file)
|
153
|
+
# Check if file exists
|
154
|
+
if (!exist?(file))
|
155
|
+
raise GitXplorer::Error::NoFileOrDirectory.new(file)
|
156
|
+
end
|
157
|
+
|
158
|
+
file, _, rev = absolute_path(file).partition(":")
|
159
|
+
|
160
|
+
# Get target and ensure it's a file
|
161
|
+
target = @tree.get(file)
|
162
|
+
if (!target.is_a?(GitXplorer::GitObject::File))
|
163
|
+
raise GitXplorer::Error::NotFile.new(file)
|
164
|
+
end
|
165
|
+
|
166
|
+
# If revision was specified, ensure it exists
|
167
|
+
if (!rev.empty? && !target.has_child?(rev))
|
168
|
+
raise GitXplorer::Error::InvalidRevision.new(rev)
|
169
|
+
end
|
170
|
+
|
171
|
+
# Default to newest revision
|
172
|
+
rev = target.newest.name if (rev.empty?)
|
173
|
+
|
174
|
+
system("git --no-pager show #{rev}:#{file}")
|
175
|
+
end
|
176
|
+
|
177
|
+
def vim(file, readonly = false)
|
178
|
+
# Check if file exists
|
179
|
+
if (!exist?(file))
|
180
|
+
raise GitXplorer::Error::NoFileOrDirectory.new(file)
|
181
|
+
end
|
182
|
+
|
183
|
+
file, _, rev = absolute_path(file).partition(":")
|
184
|
+
|
185
|
+
# Get target and ensure it's a file
|
186
|
+
target = @tree.get(file)
|
187
|
+
if (!target.is_a?(GitXplorer::GitObject::File))
|
188
|
+
raise GitXplorer::Error::NotFile.new(file)
|
189
|
+
end
|
190
|
+
|
191
|
+
# If revision was specified, ensure it exists
|
192
|
+
if (!rev.empty? && !target.has_child?(rev))
|
193
|
+
raise GitXplorer::Error::InvalidRevision.new(rev)
|
194
|
+
end
|
195
|
+
|
196
|
+
# Default to newest revision
|
197
|
+
rev = target.newest.name if (rev.empty?)
|
198
|
+
|
199
|
+
op = nil
|
200
|
+
op = "vi" if (ScoobyDoo.where_are_you("vi"))
|
201
|
+
op = "vim" if (ScoobyDoo.where_are_you("vim"))
|
202
|
+
|
203
|
+
readonly ||= false
|
204
|
+
if (readonly && op.nil?)
|
205
|
+
system("git show #{rev}:#{file}")
|
206
|
+
else
|
207
|
+
name = "/tmp/gitXplorer_"
|
208
|
+
name += File.read("/dev/urandom", 4).unpack("H*").join
|
209
|
+
File.open(name, "w") do |f|
|
210
|
+
f.write(%x(git show #{rev}:#{file}))
|
211
|
+
end
|
212
|
+
system("#{op}#{" -R" if (readonly)} #{name}")
|
213
|
+
FileUtils.rm_f(name)
|
214
|
+
end
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
require "git_xplorer/error"
|
219
|
+
require "git_xplorer/git_object"
|
metadata
ADDED
@@ -0,0 +1,152 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: gitXplorer
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Miles Whittaker
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2019-01-17 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rake
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '12.3'
|
20
|
+
- - ">="
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 12.3.2
|
23
|
+
type: :development
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - "~>"
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '12.3'
|
30
|
+
- - ">="
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 12.3.2
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: djinni
|
35
|
+
requirement: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - "~>"
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '2.2'
|
40
|
+
- - ">="
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
version: 2.2.4
|
43
|
+
type: :runtime
|
44
|
+
prerelease: false
|
45
|
+
version_requirements: !ruby/object:Gem::Requirement
|
46
|
+
requirements:
|
47
|
+
- - "~>"
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: '2.2'
|
50
|
+
- - ">="
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: 2.2.4
|
53
|
+
- !ruby/object:Gem::Dependency
|
54
|
+
name: hilighter
|
55
|
+
requirement: !ruby/object:Gem::Requirement
|
56
|
+
requirements:
|
57
|
+
- - "~>"
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
version: '1.2'
|
60
|
+
- - ">="
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: 1.2.3
|
63
|
+
type: :runtime
|
64
|
+
prerelease: false
|
65
|
+
version_requirements: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - "~>"
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '1.2'
|
70
|
+
- - ">="
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
version: 1.2.3
|
73
|
+
- !ruby/object:Gem::Dependency
|
74
|
+
name: scoobydoo
|
75
|
+
requirement: !ruby/object:Gem::Requirement
|
76
|
+
requirements:
|
77
|
+
- - "~>"
|
78
|
+
- !ruby/object:Gem::Version
|
79
|
+
version: '0.1'
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: 0.1.6
|
83
|
+
type: :runtime
|
84
|
+
prerelease: false
|
85
|
+
version_requirements: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0.1'
|
90
|
+
- - ">="
|
91
|
+
- !ruby/object:Gem::Version
|
92
|
+
version: 0.1.6
|
93
|
+
description: GitXplorer will start a shell-like session that simulates a filesystem.
|
94
|
+
Easily navigate through directories and browse all files across all revisions.
|
95
|
+
email: mjwhitta@gmail.com
|
96
|
+
executables:
|
97
|
+
- gitX
|
98
|
+
- gitx
|
99
|
+
- gitXplorer
|
100
|
+
- gitxplorer
|
101
|
+
extensions: []
|
102
|
+
extra_rdoc_files: []
|
103
|
+
files:
|
104
|
+
- bin/gitX
|
105
|
+
- bin/gitXplorer
|
106
|
+
- bin/gitx
|
107
|
+
- bin/gitxplorer
|
108
|
+
- lib/git_xplorer.rb
|
109
|
+
- lib/git_xplorer/error.rb
|
110
|
+
- lib/git_xplorer/error/invalid_revision.rb
|
111
|
+
- lib/git_xplorer/error/no_chaining_allowed.rb
|
112
|
+
- lib/git_xplorer/error/no_file_or_directory.rb
|
113
|
+
- lib/git_xplorer/error/no_semicolons_allowed.rb
|
114
|
+
- lib/git_xplorer/error/no_subshells_allowed.rb
|
115
|
+
- lib/git_xplorer/error/not_directory.rb
|
116
|
+
- lib/git_xplorer/error/not_file.rb
|
117
|
+
- lib/git_xplorer/git_object.rb
|
118
|
+
- lib/git_xplorer/git_object/directory.rb
|
119
|
+
- lib/git_xplorer/git_object/file.rb
|
120
|
+
- lib/git_xplorer/git_object/revision.rb
|
121
|
+
- lib/git_xplorer/wish/cat_wish.rb
|
122
|
+
- lib/git_xplorer/wish/change_directory_wish.rb
|
123
|
+
- lib/git_xplorer/wish/find_wish.rb
|
124
|
+
- lib/git_xplorer/wish/git_wish.rb
|
125
|
+
- lib/git_xplorer/wish/grep_wish.rb
|
126
|
+
- lib/git_xplorer/wish/list_directory_wish.rb
|
127
|
+
- lib/git_xplorer/wish/pwd_wish.rb
|
128
|
+
- lib/git_xplorer/wish/vi_wish.rb
|
129
|
+
homepage: https://gitlab.com/mjwhitta/gitXplorer
|
130
|
+
licenses:
|
131
|
+
- GPL-3.0
|
132
|
+
metadata: {}
|
133
|
+
post_install_message:
|
134
|
+
rdoc_options: []
|
135
|
+
require_paths:
|
136
|
+
- lib
|
137
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
138
|
+
requirements:
|
139
|
+
- - ">="
|
140
|
+
- !ruby/object:Gem::Version
|
141
|
+
version: '0'
|
142
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
143
|
+
requirements:
|
144
|
+
- - ">="
|
145
|
+
- !ruby/object:Gem::Version
|
146
|
+
version: '0'
|
147
|
+
requirements: []
|
148
|
+
rubygems_version: 3.0.2
|
149
|
+
signing_key:
|
150
|
+
specification_version: 4
|
151
|
+
summary: Simulate a Linux shell to browse a git tree.
|
152
|
+
test_files: []
|