Skip to content

Commit

Permalink
Save/load shell mode history - closes #79
Browse files Browse the repository at this point in the history
  • Loading branch information
chrisdambrosio committed Dec 8, 2014
1 parent 14d6154 commit 1cf656f
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 1 deletion.
10 changes: 9 additions & 1 deletion lib/gitlab/shell.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
require 'gitlab'
require 'gitlab/help'
require 'gitlab/cli_helpers'
require 'gitlab/shell_history'
require 'readline'
require 'shellwords'

Expand All @@ -9,6 +10,7 @@ class Gitlab::Shell

# Start gitlab shell and run infinite loop waiting for user input
def self.start
history.load
actions = Gitlab.actions

comp = proc { |s| actions.map(&:to_s).grep(/^#{Regexp.escape(s)}/) }
Expand All @@ -18,10 +20,12 @@ def self.start

client = Gitlab::Client.new(endpoint: '')

while buf = Readline.readline('gitlab> ', true)
while buf = Readline.readline('gitlab> ')
next if buf.nil? || buf.empty?
break if buf == 'exit'

history.save(buf)

begin
buf = Shellwords.shellwords(buf)
rescue ArgumentError => e
Expand Down Expand Up @@ -69,4 +73,8 @@ def self.start
output_table(cmd, args, data)
end
end

def self.history
@history ||= History.new
end
end
52 changes: 52 additions & 0 deletions lib/gitlab/shell_history.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
class Gitlab::Shell
class History
DEFAULT_FILE_PATH = File.join(Dir.home, '.gitlab_shell_history')

def initialize(options = {})
@file_path = options[:file_path] || DEFAULT_FILE_PATH
Readline::HISTORY.clear
end

def load
read_from_file { |line| Readline::HISTORY << line.chomp }
end

def save(line)
Readline::HISTORY << line
history_file.puts line if history_file
end

def lines
Readline::HISTORY.to_a
end

private

def history_file
if defined?(@history_file)
@history_file
else
@history_file = File.open(history_file_path, 'a', 0600).tap do |file|
file.sync = true
end
end
rescue Errno::EACCES
warn 'History not saved; unable to open your history file for writing.'
@history_file = false
end

def history_file_path
File.expand_path(@file_path)
end

def read_from_file
path = history_file_path

if File.exist?(path)
File.foreach(path) { |line| yield(line) }
end
rescue => error
warn "History file not loaded: #{error.message}"
end
end
end
2 changes: 2 additions & 0 deletions spec/fixtures/shell_history.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
party on, dudes
be excellent to each other
40 changes: 40 additions & 0 deletions spec/gitlab/shell_history_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
require 'spec_helper'
require 'tempfile'

describe Gitlab::Shell::History do
context 'saving to a file' do
before do
@file = Tempfile.new('.gitlab_shell_history')
@history = Gitlab::Shell::History.new(file_path: @file.path)
end

after do @file.close(true) end

it 'saves the lines' do
@history.save('party on, dudes')
@history.save('be excellent to each other')
expect(File.read @file.path).
to eq("party on, dudes\nbe excellent to each other\n")
end

it 'has the lines' do
@history.save('party on, dudes')
@history.save('be excellent to each other')
expect(@history.lines).
to eq(["party on, dudes", "be excellent to each other"])
end
end

context 'loading a file' do
before do
@file = load_fixture('shell_history')
@history = Gitlab::Shell::History.new(file_path: @file.path)
end

it 'has the lines' do
@history.load
expect(@history.lines).
to eq(["party on, dudes", "be excellent to each other"])
end
end
end

0 comments on commit 1cf656f

Please sign in to comment.