runssh 0.4.1 → 0.4.2

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- runssh (0.3.0.beta.3)
4
+ runssh (0.4.2)
5
5
  highline (~> 1.6.1)
6
6
  trollop (~> 1.16.2)
7
7
 
data/README.rdoc CHANGED
@@ -12,27 +12,31 @@ I am planning to add scp support as well.
12
12
  This requires you to have the _ssh_ binary in your path and optionally the
13
13
  <i>ssh-copy-id</i> binary (for copying ssh key).
14
14
 
15
- === Installation
15
+ == Installation
16
16
  You must have ruby[http://www.ruby-lang.org/] and
17
17
  rubygems[http://rubygems.org/] installed and then run:
18
18
  gem install runssh
19
19
 
20
+ === Zsh Completion
21
+ Finally we have a <b>fully functional</b> zsh completion. It includes options, subcommands
22
+ and path completions.
23
+
24
+ To install just copy the <tt>completions/_runssh</tt> file which is included in the gem (run
25
+ <tt>gem contents runssh</tt> to get the path to this file) to one of the directories in your
26
+ <tt>$fpath</tt>.
27
+
28
+ Note: I don't really know how it works. I just read some docs, looked at a few
29
+ samples (mainly _cvs) and went through a _lot_ of trial and error until it worked for
30
+ me. I hope it'll work for you as well :)
31
+
20
32
  === Bash Completion
21
- For bash completion I added a simple <tt>runssh_comp.sh</tt> file which completes
22
- the subcommands and the paths, but not the arguments. To use it, just copy
23
- it from your gem's +bin+ directory to <tt>/etc/bash-completion.d/</tt> (or wherever
24
- your bash-completion scripts are).
33
+ Bash completion is not as complete as the zsh one. It only supports path completions.
34
+ Since I'm now using zsh, I have very little interest in improving this. Anybody willing
35
+ to contribute?
25
36
 
26
- === Zsh Completion
27
- For zsh - Until I'll write a proper zsh completion file - I'm using bashcompinit
28
- to use the bash completion script. To use the bash completion file with zsh, copy
29
- the file to some place and switch the comments between line 14 and 15. Then add
30
- the following to your .zshrc file:
31
- autoload bashcompinit
32
- bashcompinit
33
- source /path/to/modified/runssh_comp.sh
34
- This works for me, but I'm only starting with zsh so I hope it will work for you
35
- as well.
37
+ To install just copy the <tt>completions/runssh_comp.sh</tt> file which is included in the gem (run
38
+ <tt>gem contents runssh</tt> to get the path to this file) to <tt>/etc/bash-completion.d/</tt>
39
+ (or wherever your bash completion files reside).
36
40
 
37
41
  == Usage
38
42
  For usage run _runssh_ without arguments.
@@ -132,6 +136,12 @@ and there's no going back ...)
132
136
  === 0.4.1
133
137
  * Doc fixes regarding version skip.
134
138
 
139
+ === 0.4.2
140
+ * If, when exporting, the output file exists, the user is prompted for approval.
141
+ * Completion now works for commands that requires options (e.g. add) even if
142
+ the required option is not given.
143
+ * Finally - proper zsh completion :)
144
+
135
145
  == TODO
136
146
  * Create a _proper_ zsh completion script.
137
147
  * Add scp capabilities.
@@ -0,0 +1,93 @@
1
+ #compdef runssh
2
+
3
+ _runssh() {
4
+ _arguments \
5
+ '(* -)'{-h,--help}'[print help]' \
6
+ '(* -)'{-v,--version}'[print version and exit]' \
7
+ '(-f --config-file)'{-f,--config-file}'+[bookmarks file]: : _files' \
8
+ '(* -)'{-U,--update-config}'[Update config version (after upgrade)]' \
9
+ '*:: :_runssh_commands'
10
+ }
11
+
12
+ (( $+funtions[_runssh_commands] )) ||
13
+ _runssh_commands() {
14
+ if (( CURRENT == 1 )); then
15
+ _describe -t commands 'runssh commands' "(shell add del update print import export cpid)" && ret=0
16
+ else
17
+ # Since we're using a syntax that clears $words we have to get
18
+ # the custom config file (if given) somehow.
19
+ [[ -n "$opt_args[-f]" ]] && runssh_config_file="-f $opt_args[-f]"
20
+ subcommand=$words[1]
21
+ case $subcommand in
22
+ shell|del|print|import|export|cpid)
23
+ _call_function ret _runssh_subcmd_$subcommand
24
+ ;;
25
+ add|update) # they have the same options
26
+ _call_function ret _runssh_subcmd_add
27
+ ;;
28
+ *) # we can not identify the subcommand but since the user
29
+ # might have used abbreviations, we'll just complete the path.
30
+ _call_function ret _runssh_path_completions
31
+ ;;
32
+ esac
33
+ fi
34
+ }
35
+
36
+ (( $+functions[_runssh_subcmd_shell] )) ||
37
+ _runssh_subcmd_shell() {
38
+ _arguments \
39
+ '(-l --login)'{-l,--login}'+[Override login]: :' \
40
+ '(-n --host-name)'{-n,--host-name}'+[host to connect to]: :' \
41
+ '*: :_runssh_path_completions'
42
+ }
43
+
44
+ (( $+functions[_runssh_subcmd_cpid] )) ||
45
+ _runssh_subcmd_cpid() {
46
+ _arguments \
47
+ '(-i --identity-file)'{-i,--identity-file}'+[Ssh key to copy]: : _files' \
48
+ '*: :_runssh_path_completions'
49
+ }
50
+
51
+ (( $+functions[_runssh_subcmd_import] )) ||
52
+ _runssh_subcmd_import() {
53
+ _arguments \
54
+ '(-i --input-file)'{-i,--input-file}'+[Yaml file to import]: : _files'\
55
+ }
56
+
57
+ (( $+functions[_runssh_subcmd_export] )) ||
58
+ _runssh_subcmd_export() {
59
+ _arguments \
60
+ '(-o --output-file)'{-o,--output-file}'+[File to export to]: : _files'\
61
+ }
62
+
63
+ (( $+functions[_runssh_subcmd_del] )) ||
64
+ _runssh_subcmd_del() {
65
+ _arguments \
66
+ '(-y --yes)'{-y,--yes}'[Delete without asking]' \
67
+ '*: :_runssh_path_completions'
68
+ }
69
+
70
+ (( $+functions[_runssh_subcmd_print] )) ||
71
+ _runssh_subcmd_print() {
72
+ _arguments \
73
+ '*: :_runssh_path_completions'
74
+ }
75
+
76
+ (( $+functions[_runssh_subcmd_add] )) ||
77
+ _runssh_subcmd_add() {
78
+ _arguments \
79
+ '(-l --login)'{-l,--login}'+[Login user]: :' \
80
+ '(-n --host-name)'{-n,--host-name}'+[host to connect to]: :' \
81
+ '(-L --local-tunnel)'{-L,--local-tunnel}'+[Local tunnel definition]: :' \
82
+ {\*-o,\*--option}'+[Ssh option]: :' \
83
+ '(-N --no-host-key-checking)'{-N,--no-host-key-checking}"[Don't verify host key!]" \
84
+ '*: :_runssh_path_completions'
85
+ }
86
+
87
+ # Call 'runssh ... ?' and get possible completions
88
+ (( $+functions[_runssh_path_completions] )) ||
89
+ _runssh_path_completions() {
90
+ completion_command="runssh $runssh_config_file $words[0,CURRENT-1] \? 2>/dev/null"
91
+ path_completions="( $(_call_program paths $completion_command ) )"
92
+ _describe -t paths 'available paths' $path_completions && ret=0
93
+ }
@@ -11,8 +11,7 @@ function _runssh () {
11
11
  fi
12
12
  # complete path or commands according to the position.
13
13
  if [ ${COMP_CWORD} -gt $COM_POSITION ]; then
14
- options=$(${COMP_WORDS[@]:0:COMP_CWORD} ? 2>/dev/null) # BASH
15
- # options=$(${COMP_WORDS[0,COMP_CWORD-1]} ? 2>/dev/null) # ZSH
14
+ options=$(${COMP_WORDS[@]:0:COMP_CWORD} ? 2>/dev/null)
16
15
  elif [ $COMP_CWORD -eq $COM_POSITION ]; then
17
16
  options="shell cpid add del update print import export"
18
17
  fi
data/lib/runsshlib/cli.rb CHANGED
@@ -61,7 +61,7 @@ EOS
61
61
  # workaround to enable 'help COMMAND' functionality.
62
62
  if args.first == 'help'; args.shift; args << '-h'; end
63
63
  # indicate path completion request
64
- @completion_requested = args.delete('?')
64
+ @completion_requested = args.delete('?') ? true : false # flag for required options
65
65
  @cmd = extract_subcommand(args)
66
66
  @options = parse_subcommand(@cmd, args)
67
67
  @c = init_config
@@ -263,7 +263,7 @@ EOH
263
263
  options = Trollop::options(args) do
264
264
  banner help
265
265
  opt :host_name, 'The name or address of the host (e.g, host.example.com).',
266
- :short => :n, :type => :string, :required => true
266
+ :short => :n, :type => :string, :required => @completion_requested
267
267
  opt :login, 'The login to connect as.',
268
268
  :type => :string
269
269
  opt :local_tunnel, "Tunnel definition (see description above).",
@@ -403,6 +403,10 @@ EOS
403
403
 
404
404
  # we don't use path here, it's just for easier invocation
405
405
  def run_export(path)
406
+ if File.exist? @options[:output_file]
407
+ question = "Output file (#{@options[:output_file]}) exists!. Overwrite? [yes/no] "
408
+ agree_or_abort question, 'Cancelled'
409
+ end
406
410
  @c.export(@options[:output_file])
407
411
  end
408
412
 
@@ -20,7 +20,7 @@ module RunSSHLib
20
20
  module Version
21
21
  MAJOR = 0
22
22
  MINOR = 4
23
- BUILD = 1
23
+ BUILD = 2
24
24
 
25
25
  STRING = [MAJOR, MINOR, BUILD].compact.join('.')
26
26
  end
@@ -21,7 +21,7 @@ require 'stringio'
21
21
  require 'yaml'
22
22
 
23
23
  describe "The CLI interface" do
24
- context "argument parser" do
24
+ context "global options parsing" do
25
25
  it "should correctly process the -f argument" do
26
26
  cli = RunSSHLib::CLI.new(%W(-f #{TMP_FILE} print test))
27
27
  global_options = cli.instance_variable_get :@global_options
@@ -48,7 +48,9 @@ describe "The CLI interface" do
48
48
  end.to exit_abnormaly
49
49
  @buf.should match(/invalid command/)
50
50
  end
51
+ end
51
52
 
53
+ context "completion mechanism" do
52
54
  it "displays completions and exit if requested" do
53
55
  import_fixtures
54
56
  capture(:stdout) {
@@ -57,6 +59,15 @@ describe "The CLI interface" do
57
59
  @buf.should include("cust1")
58
60
  @buf.should include("cust2")
59
61
  end
62
+
63
+ it "displays completion even if required option for subcommand is missing" do
64
+ import_fixtures
65
+ capture(:stdout) {
66
+ RunSSHLib::CLI.new(%W(-f #{TMP_FILE} update ?)).run
67
+ }
68
+ @buf.should include("cust1")
69
+ @buf.should include("cust2")
70
+ end
60
71
  end
61
72
 
62
73
  context "help" do
@@ -214,6 +225,39 @@ describe "The CLI interface" do
214
225
  end
215
226
  end
216
227
 
228
+ describe "export subcommand" do
229
+ context "when export file exists" do
230
+ let(:cli) {
231
+ RunSSHLib::CLI::new(%W(-f #{TMP_FILE} export -o #{TMP_YML}))
232
+ }
233
+
234
+ before(:each) do
235
+ File.open(TMP_YML, 'w') { |io| io.write "" }
236
+ end
237
+
238
+ it "overwrites the file if the user approves the prompt" do
239
+ capture(:stderr) do
240
+ capture(:stdout, 'yes') do
241
+ cli.run
242
+ end
243
+ end
244
+ @buf.should include('Overwrite?')
245
+ @buf.should include(TMP_YML)
246
+ IO.read(TMP_YML).should_not == ""
247
+ end
248
+
249
+ it "correctly cancels exporting if answered no at the prompt" do
250
+ capture(:stdout) do
251
+ capture(:stderr, 'no') do
252
+ expect { cli.run }.to exit_abnormaly
253
+ end
254
+ end
255
+ @buf.should include('Cancelled')
256
+ IO.read(TMP_YML).should == ''
257
+ end
258
+ end
259
+ end
260
+
217
261
  context "Add bookmark with ssh options" do
218
262
  it "adds options specified with '-o' to the '--no-host-key-checking' options" do
219
263
  options = %W(-f #{TMP_FILE} add -o ForwardAgent=true --no-host-key-checking -n some.host one two)
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: runssh
3
3
  version: !ruby/object:Gem::Version
4
- hash: 13
4
+ hash: 11
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 4
9
- - 1
10
- version: 0.4.1
9
+ - 2
10
+ version: 0.4.2
11
11
  platform: ruby
12
12
  authors:
13
13
  - Haim Ashkenazi
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-05-03 00:00:00 +03:00
18
+ date: 2011-05-07 00:00:00 +03:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -71,7 +71,8 @@ files:
71
71
  - Rakefile
72
72
  - autotest/discover.rb
73
73
  - bin/runssh
74
- - bin/runssh_comp.sh
74
+ - completions/_runssh
75
+ - completions/runssh_comp.sh
75
76
  - features/add_bookmarks.feature
76
77
  - features/cli_help.feature
77
78
  - features/copy_id.feature