runssh 0.4.1 → 0.4.2

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.
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