gitXplorer 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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: []
|