poet 0.4 → 0.5
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/.travis.yml +7 -1
- data/History.txt +18 -0
- data/README.md +15 -5
- data/bin/poet +1 -33
- data/features/bootstrapping.feature +4 -4
- data/features/editing_files.feature +32 -0
- data/features/step_definitions/editor_steps.rb +3 -0
- data/features/verbose.feature +29 -0
- data/lib/poet.rb +65 -49
- data/lib/poet/version.rb +1 -1
- data/poet.gemspec +1 -0
- metadata +27 -10
data/.travis.yml
CHANGED
data/History.txt
CHANGED
@@ -1,5 +1,23 @@
|
|
1
1
|
master
|
2
2
|
|
3
|
+
0.5
|
4
|
+
|
5
|
+
- drop support for Ruby 1.8
|
6
|
+
|
7
|
+
- edit files under ~/.ssh/config.d/ directly with `poet edit some_ssh_config_file`
|
8
|
+
|
9
|
+
- use Thor internally for CLI
|
10
|
+
|
11
|
+
- 'bootstrap' is now a subcommand (use `poet bootstrap` instead of `poet --bootstrap`)
|
12
|
+
|
13
|
+
- also test against JRuby, Rubinius, and 1.9.2
|
14
|
+
|
15
|
+
- running verbosely works again
|
16
|
+
|
17
|
+
- extended help
|
18
|
+
|
19
|
+
0.4
|
20
|
+
|
3
21
|
- let users organize their config files in directories
|
4
22
|
|
5
23
|
0.3.1
|
data/README.md
CHANGED
@@ -1,16 +1,26 @@
|
|
1
1
|
[](http://travis-ci.org/awendt/poet)
|
2
2
|
|
3
|
-
#
|
3
|
+
# Split your `ssh_config` into separate files!
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
5
|
+
## Getting started
|
6
|
+
|
7
|
+
$ gem install poet
|
8
|
+
$ poet bootstrap
|
9
|
+
|
10
|
+
This will move your `~/.ssh/config` into `~/.ssh/config.d/` and create an identical `~/.ssh/config`.
|
11
|
+
Organize files in `~/.ssh/config.d/` any way you want (just remember to re-run `poet` afterwards).
|
12
|
+
|
13
|
+
To edit `~/.ssh/config.d/some_file`, run `poet edit some_file`.
|
14
|
+
Poet will open your favorite $EDITOR and automatically create a new `~/.ssh/config`
|
15
|
+
when you quit the editor.
|
16
|
+
|
17
|
+
## Advanced usage
|
8
18
|
|
9
19
|
Poet won't touch your existing ssh_config.
|
10
20
|
If you want to play with it, pass a different filename to the "-o" option.
|
11
21
|
Or move your existing config out of the way.
|
12
22
|
|
13
|
-
Stanzas under `~/.ssh/config.d/` with an extension of .disabled are ignored by
|
23
|
+
Stanzas under `~/.ssh/config.d/` with an extension of .disabled are ignored by default.
|
14
24
|
Every now and then, when you do need it, run `poet --with CONFIG` to explicitly include
|
15
25
|
`CONFIG.disabled` in your generated ssh_config. You can even include several by running several
|
16
26
|
`--with` options or using `--with CONFIG1,CONFIG2`.
|
data/bin/poet
CHANGED
@@ -1,37 +1,5 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
-
require 'optparse'
|
4
3
|
require 'poet'
|
5
4
|
|
6
|
-
|
7
|
-
:ssh_config => ENV['POET_OUTPUT'] || File.expand_path('~/.ssh/config'),
|
8
|
-
:verbose => false,
|
9
|
-
:with => [],
|
10
|
-
:dir => ENV['POET_GLOBDIR'] || File.expand_path('~/.ssh/config.d')
|
11
|
-
}
|
12
|
-
|
13
|
-
optparse = OptionParser.new do|opts|
|
14
|
-
opts.on('-h', '--help', 'Display this screen') do
|
15
|
-
puts opts
|
16
|
-
exit
|
17
|
-
end
|
18
|
-
opts.on('-d', '--dir DIR', '') do |dir|
|
19
|
-
options[:dir] = File.expand_path(dir)
|
20
|
-
end
|
21
|
-
opts.on('-o', '--output FILE', '') do |file|
|
22
|
-
options[:ssh_config] = file
|
23
|
-
end
|
24
|
-
opts.on('-v', '--verbose', 'Be verbose') do
|
25
|
-
options[:verbose] = true
|
26
|
-
end
|
27
|
-
opts.on('--bootstrap [FILE]', '') do |file|
|
28
|
-
options[:bootstrap] = File.expand_path(file || options[:ssh_config])
|
29
|
-
end
|
30
|
-
opts.on('-w', '--with CONFIG', 'Include an otherwise disabled config file') do |file|
|
31
|
-
options[:with] += file.split(',')
|
32
|
-
options[:with].each{|file| puts "Including #{file} even if disabled..."}
|
33
|
-
end
|
34
|
-
end
|
35
|
-
optparse.parse!
|
36
|
-
|
37
|
-
Poet.application(options).run
|
5
|
+
PoetCLI.start(ARGV)
|
@@ -8,7 +8,7 @@ Feature: Bootstrapping
|
|
8
8
|
Host *.amazonaws.com
|
9
9
|
StrictHostKeyChecking no
|
10
10
|
"""
|
11
|
-
When I run `poet
|
11
|
+
When I run `poet bootstrap --dir ./config.d`
|
12
12
|
Then the exit status should be 0
|
13
13
|
And a directory named "config.d" should exist
|
14
14
|
And a file named "config.d/ssh_config" should exist
|
@@ -24,8 +24,8 @@ Feature: Bootstrapping
|
|
24
24
|
Host *.amazonaws.com
|
25
25
|
StrictHostKeyChecking no
|
26
26
|
"""
|
27
|
-
When I run `poet
|
27
|
+
When I run `poet bootstrap --dir ./config.d`
|
28
28
|
Then the exit status should be 0
|
29
|
-
When I run `poet
|
30
|
-
Then the output from "poet
|
29
|
+
When I run `poet bootstrap --dir ./config.d`
|
30
|
+
Then the output from "poet bootstrap --dir ./config.d" should contain "You're already good to go"
|
31
31
|
And the exit status should not be 0
|
@@ -0,0 +1,32 @@
|
|
1
|
+
Feature: Editing files
|
2
|
+
Scenario: User wants to edit files quickly
|
3
|
+
Given a file named "favorite_editor" with:
|
4
|
+
"""
|
5
|
+
Host vim
|
6
|
+
User me
|
7
|
+
"""
|
8
|
+
When I set env variable "EDITOR" to "/bin/cat"
|
9
|
+
And I run `poet edit favorite_editor`
|
10
|
+
Then the output from "poet edit favorite_editor" should contain "Host vim"
|
11
|
+
And the file "ssh_config" should contain "Host vim"
|
12
|
+
|
13
|
+
Scenario: Show warning when user does not have EDITOR set
|
14
|
+
Given a file named "no_editor" with:
|
15
|
+
"""
|
16
|
+
Host none
|
17
|
+
User me
|
18
|
+
"""
|
19
|
+
When I set env variable "EDITOR" to ""
|
20
|
+
And I run `poet edit no_editor`
|
21
|
+
Then the output from "poet edit no_editor" should contain "$EDITOR is empty. Could not determine your favorite editor."
|
22
|
+
And the exit status should not be 0
|
23
|
+
|
24
|
+
Scenario: Do not re-create ssh_config when no file was created
|
25
|
+
Given a file named "important" with:
|
26
|
+
"""
|
27
|
+
This is absolutely vital information
|
28
|
+
"""
|
29
|
+
When I set env variable "EDITOR" to "/bin/cat"
|
30
|
+
And I run `poet edit missing -o important`
|
31
|
+
Then the output from "poet edit missing -o important" should not contain "Found hand-crafted ssh_config"
|
32
|
+
And the exit status should be 0
|
@@ -0,0 +1,29 @@
|
|
1
|
+
Feature: Seeing more output when running verbosely
|
2
|
+
Scenario: Silent by default
|
3
|
+
Given a file named "test" with:
|
4
|
+
"""
|
5
|
+
Host te.st
|
6
|
+
User me
|
7
|
+
"""
|
8
|
+
When I run `poet`
|
9
|
+
Then the output should not contain "Using test"
|
10
|
+
|
11
|
+
Scenario: User sees which files are included
|
12
|
+
Given a directory named "customers"
|
13
|
+
And a file named "customers/first" with:
|
14
|
+
"""
|
15
|
+
Host customer1
|
16
|
+
User me
|
17
|
+
"""
|
18
|
+
And a file named "customers/second" with:
|
19
|
+
"""
|
20
|
+
Host customer2
|
21
|
+
User me
|
22
|
+
"""
|
23
|
+
When I run `poet -v`
|
24
|
+
Then the output should contain exactly:
|
25
|
+
"""
|
26
|
+
Using customers/first
|
27
|
+
Using customers/second
|
28
|
+
|
29
|
+
"""
|
data/lib/poet.rb
CHANGED
@@ -1,71 +1,87 @@
|
|
1
1
|
require "poet/version"
|
2
|
+
require "thor"
|
2
3
|
require "fileutils"
|
3
4
|
|
4
|
-
|
5
|
+
class PoetCLI < Thor
|
5
6
|
|
6
7
|
MAGIC_LINE = "# Generated by #{File.basename(__FILE__, '.rb')}"
|
7
8
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
default_task :create
|
10
|
+
class_option :dir,
|
11
|
+
desc: 'Use specified directory to collect conf files',
|
12
|
+
default: ENV['POET_GLOBDIR'] || File.expand_path('~/.ssh/config.d')
|
13
|
+
class_option :output,
|
14
|
+
desc: 'Generate output in specified file',
|
15
|
+
aliases: '-o',
|
16
|
+
default: ENV['POET_OUTPUT'] || File.expand_path('~/.ssh/config')
|
17
|
+
class_option :with,
|
18
|
+
desc: 'Include an otherwise disabled config file',
|
19
|
+
aliases: '-w',
|
20
|
+
default: ""
|
21
|
+
class_option :verbose,
|
22
|
+
desc: 'Be verbose',
|
23
|
+
aliases: '-v',
|
24
|
+
type: :boolean
|
25
|
+
|
26
|
+
desc "bootstrap [FILE]",
|
27
|
+
"Move ~/.ssh/config (or whatever you specified) to ~/.ssh/config.d/ to help you get started"
|
28
|
+
def bootstrap(file=nil)
|
29
|
+
file ||= File.expand_path(file || options[:output])
|
30
|
+
if File.directory?(options[:dir])
|
31
|
+
$stderr.puts "You're already good to go."
|
32
|
+
Process.exit!(3)
|
12
33
|
end
|
13
|
-
|
34
|
+
FileUtils.mkdir_p(options[:dir])
|
35
|
+
FileUtils.mv(file, options[:dir])
|
36
|
+
create
|
14
37
|
end
|
15
38
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
@options = options
|
39
|
+
desc "", "Concatenate all host stanzas under ~/.ssh/config.d/ into a single ~/.ssh/config"
|
40
|
+
def create
|
41
|
+
if !File.directory?(options[:dir])
|
42
|
+
$stderr.puts "#{options[:dir]} does not exist or is not a directory"
|
43
|
+
Process.exit!(1)
|
22
44
|
end
|
23
45
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
FileUtils.mkdir_p(options[:dir])
|
30
|
-
FileUtils.mv(options[:bootstrap], options[:dir])
|
46
|
+
if File.exists?(options[:output]) && File.new(options[:output]).gets == "#{MAGIC_LINE}\n"
|
47
|
+
puts "Found generated ssh_config under #{options[:output]}. Overwriting..."
|
48
|
+
elsif File.exists?(options[:output])
|
49
|
+
$stderr.puts "Found hand-crafted ssh_config under #{options[:output]}. Please move it out of the way or specify a different output file with the -o option."
|
50
|
+
Process.exit!(2)
|
31
51
|
end
|
32
52
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
Process.exit!(1)
|
39
|
-
end
|
40
|
-
|
41
|
-
if File.exists?(options[:ssh_config]) && File.new(options[:ssh_config]).gets == "#{MAGIC_LINE}\n"
|
42
|
-
puts "Found generated ssh_config under #{options[:ssh_config]}. Overwriting..."
|
43
|
-
elsif File.exists?(options[:ssh_config])
|
44
|
-
$stderr.puts "Found hand-crafted ssh_config under #{options[:ssh_config]}. Please move it out of the way or specify a different output file with the -o option."
|
45
|
-
Process.exit!(2)
|
46
|
-
end
|
53
|
+
whitelist = options[:with].split(',')
|
54
|
+
files = Dir["#{options[:dir]}/**/*"].reject do |file|
|
55
|
+
File.directory?(file) || \
|
56
|
+
file =~ /\.disabled$/ && !whitelist.include?("#{File.basename(file, '.disabled')}")
|
57
|
+
end
|
47
58
|
|
48
|
-
|
49
|
-
File.directory?(file) || \
|
50
|
-
file =~ /\.disabled$/ && !options[:with].include?("#{File.basename(file, '.disabled')}")
|
51
|
-
end
|
59
|
+
files -= [options[:output]]
|
52
60
|
|
53
|
-
|
61
|
+
entries = []
|
54
62
|
|
55
|
-
|
63
|
+
files.sort.each do |file|
|
64
|
+
entries << File.read(file)
|
65
|
+
$stdout.puts "Using #{file.gsub(/^\.\//, '')}" if options[:verbose]
|
66
|
+
end
|
56
67
|
|
57
|
-
|
58
|
-
|
59
|
-
|
68
|
+
File.open(options[:output], 'w', 0600) do |ssh_config|
|
69
|
+
ssh_config.puts(MAGIC_LINE)
|
70
|
+
ssh_config.puts("# DO NOT EDIT THIS FILE")
|
71
|
+
ssh_config.puts("# Create or modify files under #{options[:dir]} instead")
|
72
|
+
ssh_config.puts(entries.join("\n"))
|
73
|
+
end
|
74
|
+
end
|
60
75
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
end
|
76
|
+
desc "edit FILE", "Open FILE under ~/.ssh/config.d/ in your favorite $EDITOR"
|
77
|
+
def edit(file)
|
78
|
+
if ENV['EDITOR'].to_s.empty?
|
79
|
+
$stderr.puts "$EDITOR is empty. Could not determine your favorite editor."
|
80
|
+
Process.exit!(4)
|
67
81
|
end
|
68
|
-
|
82
|
+
filepath = File.join(options[:dir], file)
|
83
|
+
system("#{ENV['EDITOR']} #{filepath}")
|
84
|
+
create if File.exists?(filepath)
|
69
85
|
end
|
70
86
|
|
71
87
|
end
|
data/lib/poet/version.rb
CHANGED
data/poet.gemspec
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: poet
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: '0.
|
4
|
+
version: '0.5'
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2013-02-05 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: cucumber
|
16
|
-
requirement: &
|
16
|
+
requirement: &70099056296460 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :development
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *70099056296460
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: aruba
|
27
|
-
requirement: &
|
27
|
+
requirement: &70099056296020 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: '0'
|
33
33
|
type: :development
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *70099056296020
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: rake
|
38
|
-
requirement: &
|
38
|
+
requirement: &70099056295560 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ! '>='
|
@@ -43,7 +43,18 @@ dependencies:
|
|
43
43
|
version: '0'
|
44
44
|
type: :development
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *70099056295560
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: thor
|
49
|
+
requirement: &70099056311480 !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
type: :runtime
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: *70099056311480
|
47
58
|
description: Split your longish ~/.ssh/config into files in ~/.ssh/config.d/ and let
|
48
59
|
poet join them for you.
|
49
60
|
email:
|
@@ -62,11 +73,14 @@ files:
|
|
62
73
|
- Rakefile
|
63
74
|
- bin/poet
|
64
75
|
- features/bootstrapping.feature
|
76
|
+
- features/editing_files.feature
|
65
77
|
- features/permissions.feature
|
66
78
|
- features/running.feature
|
67
79
|
- features/selective_files.feature
|
80
|
+
- features/step_definitions/editor_steps.rb
|
68
81
|
- features/step_definitions/permissions_steps.rb
|
69
82
|
- features/support/env.rb
|
83
|
+
- features/verbose.feature
|
70
84
|
- lib/poet.rb
|
71
85
|
- lib/poet/version.rb
|
72
86
|
- poet.gemspec
|
@@ -84,7 +98,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
84
98
|
version: '0'
|
85
99
|
segments:
|
86
100
|
- 0
|
87
|
-
hash: -
|
101
|
+
hash: -3487840776745573411
|
88
102
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
89
103
|
none: false
|
90
104
|
requirements:
|
@@ -93,7 +107,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
93
107
|
version: '0'
|
94
108
|
segments:
|
95
109
|
- 0
|
96
|
-
hash: -
|
110
|
+
hash: -3487840776745573411
|
97
111
|
requirements: []
|
98
112
|
rubyforge_project: poet
|
99
113
|
rubygems_version: 1.8.11
|
@@ -102,8 +116,11 @@ specification_version: 3
|
|
102
116
|
summary: Poet concatenates stanzas
|
103
117
|
test_files:
|
104
118
|
- features/bootstrapping.feature
|
119
|
+
- features/editing_files.feature
|
105
120
|
- features/permissions.feature
|
106
121
|
- features/running.feature
|
107
122
|
- features/selective_files.feature
|
123
|
+
- features/step_definitions/editor_steps.rb
|
108
124
|
- features/step_definitions/permissions_steps.rb
|
109
125
|
- features/support/env.rb
|
126
|
+
- features/verbose.feature
|