thor-ssh 0.0.8

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in thor-ssh.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Ryan Stout
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,45 @@
1
+ # thor-ssh
2
+
3
+ ThorSsh takes thor and allows it to run from local to remote.
4
+ It assumes that the sources are always local and the remotes
5
+ are always remote.
6
+
7
+ ## Use
8
+ gem 'thor-ssh'
9
+
10
+ Use thor as you normally would, but on any thor instance add the following:
11
+
12
+ class ThorTest < Thor
13
+ include Thor::Actions
14
+ include ThorSsh::Actions
15
+
16
+ Then set a destination server to an Net::SSH connection to make all actions use a different server for the destination.
17
+
18
+ self.destination_server = Net::SSH.start(... [ssh connection] ...)
19
+
20
+ ## Things that don't work yet
21
+
22
+ This is still a work in progress. The main issue is that calling #inside or anything that depends on it (in_root) does not work yet. I'll get it working soon though.
23
+
24
+ TODO: Get #inside working
25
+ TODO: Add other features needed for provisioning system
26
+ TODO: Make way to copy remote to remote
27
+
28
+ ## Running Tests
29
+ The test run through vagrant, which seemed logical since we want to test ssh stuff.
30
+
31
+ ### Install a box (first time only)
32
+ cd spec/vagrant
33
+ vagrant box add ubuntu11 http://timhuegdon.com/vagrant-boxes/ubuntu-11.10.box
34
+ vagrant init ubuntu11
35
+
36
+ ### Start box
37
+ vagrant up
38
+
39
+ ### Run the tests
40
+ cd ../..
41
+ bundle exec rspec
42
+
43
+ ### When you're done
44
+ cd spec/vagrant
45
+ vagrant halt
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
@@ -0,0 +1,18 @@
1
+ # Extend create file to work over ssh
2
+ class Thor
3
+ module Actions
4
+ class CreateFile
5
+ def identical?
6
+ exists? && @base.destination_files.binread(destination) == render
7
+ end
8
+
9
+ def invoke!
10
+ invoke_with_conflict_check do
11
+ @base.destination_files.mkdir_p(File.dirname(destination))
12
+ @base.destination_files.binwrite(destination, render)
13
+ end
14
+ given_destination
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,27 @@
1
+ require 'thor-ssh/actions/create_file'
2
+
3
+ class Thor
4
+ module Actions
5
+ class CreateLink
6
+ def identical?
7
+ exists? && base.destination_files.identical?(render, destination)
8
+ end
9
+
10
+ def invoke!
11
+ invoke_with_conflict_check do
12
+ base.destination_files.mkdir_p(File.dirname(destination))
13
+ # Create a symlink by default
14
+ config[:symbolic] = true if config[:symbolic].nil?
15
+ base.destination_files.unlink(destination) if exists?
16
+ if config[:symbolic]
17
+ base.destination_files.symlink(render, destination)
18
+ else
19
+ base.destination_files.link(render, destination)
20
+ end
21
+ end
22
+ given_destination
23
+ end
24
+
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,23 @@
1
+ class Thor
2
+ module Actions
3
+ class EmptyDirectory
4
+ # Checks if the directory exists on the detination server
5
+ def exists?
6
+ @base.destination_files.exists?(destination)
7
+ end
8
+
9
+ def invoke!
10
+ invoke_with_conflict_check do
11
+ @base.destination_files.mkdir_p(destination)
12
+ end
13
+ end
14
+
15
+ def revoke!
16
+ say_status :remove, :red
17
+ @base.destination_files.rm_rf(destination) if !pretend? && exists?
18
+ given_destination
19
+ end
20
+
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,46 @@
1
+ class Thor
2
+ module Actions
3
+ # TODO: link_file doesn't make since for links into the gem
4
+ # def link_file(source, *args, &block)
5
+ # config = args.last.is_a?(Hash) ? args.pop : {}
6
+ # destination = args.first || source
7
+ # source = File.expand_path(find_in_source_paths(source.to_s))
8
+ #
9
+ # create_link destination, source, config
10
+ # end
11
+
12
+
13
+ def chmod(path, mode, config={})
14
+ return unless behavior == :invoke
15
+ path = File.expand_path(path, destination_root)
16
+ say_status :chmod, relative_to_original_destination_root(path), config.fetch(:verbose, true)
17
+
18
+ destination_files.chmod(mode, path) unless options[:pretend]
19
+ end
20
+
21
+
22
+ def gsub_file(path, flag, *args, &block)
23
+ return unless behavior == :invoke
24
+ config = args.last.is_a?(Hash) ? args.pop : {}
25
+
26
+ path = File.expand_path(path, destination_root)
27
+ say_status :gsub, relative_to_original_destination_root(path), config.fetch(:verbose, true)
28
+
29
+ unless options[:pretend]
30
+ content = destination_files.binread(path)
31
+ content.gsub!(flag, *args, &block)
32
+ destination_files.binwrite(path, content)
33
+ end
34
+ end
35
+
36
+ def remove_file(path, config={})
37
+ return unless behavior == :invoke
38
+ path = File.expand_path(path, destination_root)
39
+
40
+ say_status :remove, relative_to_original_destination_root(path), config.fetch(:verbose, true)
41
+ destination_files.rm_rf(path) if !options[:pretend] && destination_files.exists?(path)
42
+ end
43
+
44
+
45
+ end
46
+ end
@@ -0,0 +1,17 @@
1
+ require 'thor-ssh/actions/empty_directory'
2
+
3
+ class Thor
4
+ module Actions
5
+ class InjectIntoFile
6
+ def replace!(regexp, string, force)
7
+ unless base.options[:pretend]
8
+ content = base.destination_files.binread(destination)
9
+ if force || !content.include?(replacement)
10
+ content.gsub!(regexp, string)
11
+ base.destination_files.binwrite(destination, content)
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,56 @@
1
+ require 'thor-ssh/remote_file'
2
+ require 'thor-ssh/actions/empty_directory'
3
+ require 'thor-ssh/actions/create_file'
4
+ require 'thor-ssh/actions/create_link'
5
+ require 'thor-ssh/actions/file_manipulation'
6
+ require 'thor-ssh/actions/inject_into_file'
7
+
8
+ module ThorSsh
9
+ module Actions
10
+
11
+ # Returns a connection to the destination server for this thor class.
12
+ def destination_server
13
+ @destination_server
14
+ end
15
+
16
+ # Sets the destination server connection
17
+ def destination_server=(val)
18
+ @destination_server = val
19
+ end
20
+
21
+ # Returns a remote file or File object that can used to query
22
+ # or change the state of files. If there is no destination_server
23
+ # it is assumed to be local and a normal File class is returned
24
+ def destination_files
25
+ if self.destination_server
26
+ return @destination_files ||= RemoteFile.new(self.destination_server)
27
+ else
28
+ return File
29
+ end
30
+ end
31
+
32
+ def inside(dir='', config={}, &block)
33
+ raise "inside is not implemented in thor-ssh, please use full paths"
34
+ end
35
+
36
+ def run(command, config={})
37
+ return unless behavior == :invoke
38
+
39
+ destination = relative_to_original_destination_root(destination_root, false)
40
+ desc = "#{command} from #{destination.inspect}"
41
+
42
+ if config[:with]
43
+ desc = "#{File.basename(config[:with].to_s)} #{desc}"
44
+ command = "#{config[:with]} #{command}"
45
+ end
46
+
47
+ say_status :run, desc, config.fetch(:verbose, true)
48
+
49
+ unless options[:pretend]
50
+ # config[:capture] ? `#{command}` : system("#{command}")
51
+ return destination_files.run(command)
52
+ end
53
+ end
54
+
55
+ end
56
+ end
@@ -0,0 +1,84 @@
1
+ require 'net/ssh'
2
+ require 'net/sftp'
3
+
4
+ module ThorSsh
5
+ class RemoteFile
6
+ attr_reader :connection
7
+
8
+ def initialize(connection)
9
+ @connection = connection
10
+ end
11
+
12
+ def exists?(path)
13
+ begin
14
+ connection.sftp.stat!(path)
15
+ rescue Net::SFTP::StatusException
16
+ return false
17
+ end
18
+
19
+ return true
20
+ end
21
+
22
+ def run(command)
23
+ return connection.exec!(command)
24
+ end
25
+
26
+ # Creates the directory at the path on the remote server
27
+ def mkdir_p(path)
28
+ run "mkdir -p \"#{path}\""
29
+ end
30
+
31
+ # Remote the file/folder on the remote server
32
+ def rm_rf(path)
33
+ run "rm -rf \"#{path}\""
34
+ end
35
+ alias :unlink :rm_rf
36
+
37
+ def symlink(old_name, new_name)
38
+ run("ln -s \"#{old_name}\" \"#{new_name}\"")
39
+ end
40
+
41
+ def link(old_name, new_name)
42
+ run("ln \"#{old_name}\" \"#{new_name}\"")
43
+ end
44
+
45
+ def binread(path)
46
+ data = nil
47
+ connection.sftp.file.open(path, "rb") do |f|
48
+ data = f.read
49
+ end
50
+
51
+ return data
52
+ end
53
+
54
+ # TODO: we should just move this to a more standard thing
55
+ def binwrite(path, data)
56
+ file = connection.sftp.open!(path, 'wb')
57
+
58
+ # Write
59
+ connection.sftp.write!(file, 0, data)
60
+
61
+ # Close
62
+ connection.sftp.close!(file)
63
+ end
64
+
65
+ def chmod(mode, file_name)
66
+ if mode.is_a?(Integer)
67
+ # Mode is an integer, convert to octal
68
+ mode = '%04d' % mode.to_s(8)
69
+ end
70
+
71
+ return run("chmod #{mode} \"#{file_name}\"")
72
+ end
73
+
74
+ def inode(file_name)
75
+ return run("ls -i \"#{file_name}\"").strip.split(/ /).first
76
+ end
77
+
78
+ # See if these paths point to the same inode
79
+ def identical?(file1, file2)
80
+ inode(file1) == inode(file2)
81
+ end
82
+
83
+ end
84
+ end
@@ -0,0 +1,3 @@
1
+ module ThorSsh
2
+ VERSION = "0.0.8"
3
+ end
data/lib/thor-ssh.rb ADDED
@@ -0,0 +1,5 @@
1
+ require "thor-ssh/version"
2
+ require "thor-ssh/actions"
3
+
4
+ module ThorSsh
5
+ end
@@ -0,0 +1,96 @@
1
+ require 'spec_helper'
2
+ require 'thor_test'
3
+ require 'vagrant/vagrant_manager'
4
+
5
+
6
+ describe ThorSsh do
7
+ before do
8
+ # Setup the test and connect to a test server
9
+ @thor_test = ThorTest.new
10
+ @thor_test.destination_server = VagrantManager.connect
11
+ # @thor_test.destination_server = Net::SSH.start('localhost', 'ubuntu', :port => 2222)
12
+ end
13
+
14
+ after do
15
+ # Close the connection
16
+ @thor_test.destination_server.close
17
+ end
18
+
19
+ before(:all) do
20
+ @base_path = '/home/vagrant/thortest'
21
+
22
+ @thor_test = ThorTest.new
23
+ @thor_test.destination_server = VagrantManager.connect
24
+ @thor_test.destination_files.rm_rf(@base_path)
25
+ @thor_test.destination_server.close
26
+ end
27
+
28
+ it 'should create an empty directory' do
29
+ @thor_test.empty_directory(@base_path)
30
+ @thor_test.destination_files.exists?(@base_path)
31
+ end
32
+
33
+ it 'should create an empty directory' do
34
+ @thor_test.get('http://www.google.com/', "#{@base_path}/google.txt")
35
+ @thor_test.destination_files.binread("#{@base_path}/google.txt").should match(/Google/)
36
+ end
37
+
38
+ it 'should create a file and set the text' do
39
+ @thor_test.create_file("#{@base_path}/createdFile", "More awesome content\nSecond Line of content")
40
+ @thor_test.destination_files.binread("#{@base_path}/createdFile").should == "More awesome content\nSecond Line of content"
41
+ end
42
+
43
+ it "should copy in text" do
44
+ @thor_test.destination_root = @base_path + "/"
45
+ @thor_test.template "templates/test_template.rb.tt"
46
+ @thor_test.destination_files.binread("#{@base_path}/templates/test_template.rb").should match(/Test Ruby File/)
47
+ end
48
+
49
+ def mode(path)
50
+ ls = @thor_test.destination_files.run("ls -lh \"#{@base_path}/#{path}\"")
51
+ mode = ls.strip.split(/ /).first.strip
52
+ return mode
53
+ end
54
+
55
+ it "should set the mode" do
56
+ @thor_test.create_file("#{@base_path}/modeFile", "More awesome content")
57
+ mode('modeFile').should == '-rw-r--r--'
58
+ @thor_test.chmod("#{@base_path}/modeFile", 0600)
59
+ mode('modeFile').should == '-rw-------'
60
+ end
61
+
62
+ it "should gsub files" do
63
+ file = "#{@base_path}/gsubFile"
64
+ @thor_test.create_file(file, "More awesome content")
65
+ @thor_test.gsub_file file, /awesome/, 'cool'
66
+ @thor_test.destination_files.binread(file).should == 'More cool content'
67
+ end
68
+
69
+ it "should remove files" do
70
+ file = "#{@base_path}/removeFile"
71
+ @thor_test.create_file(file, "More awesome content")
72
+ @thor_test.destination_files.exists?(file).should == true
73
+ @thor_test.remove_file(file)
74
+ @thor_test.destination_files.exists?(file).should == false
75
+ end
76
+
77
+ it "should inject text into files" do
78
+ file = "#{@base_path}/injectFile"
79
+ @thor_test.create_file(file, "First line\nSecond Line\nThird Line")
80
+ @thor_test.insert_into_file(file, "2.5 line\n", :after => "Second Line\n")
81
+ @thor_test.destination_files.binread(file).should == "First line\nSecond Line\n2.5 line\nThird Line"
82
+ end
83
+
84
+ it "should create links" do
85
+ file = "#{@base_path}/symFile"
86
+ link_file = "#{@base_path}/linkedFile"
87
+ @thor_test.create_file(file, "Text")
88
+
89
+ @thor_test.create_link(link_file, file)
90
+
91
+ @thor_test.destination_files.binread(link_file).should == "Text"
92
+ end
93
+
94
+ end
95
+
96
+
@@ -0,0 +1,21 @@
1
+ require 'spec_helper'
2
+ require 'thor-ssh'
3
+
4
+ describe ThorSsh do
5
+ before do
6
+ @connection = mock(Net::SFTP)
7
+ @remote_file = ThorSsh::RemoteFile.new(@connection)
8
+ end
9
+
10
+ it "should set the connection" do
11
+ @remote_file.connection.should == @connection
12
+ end
13
+
14
+ it "should check if a remote file exists" do
15
+ sftp_connection = mock("sftp")
16
+ sftp_connection.should_receive(:stat!).with('/test/path') { true }
17
+
18
+ @connection.stub(:sftp) { sftp_connection }
19
+ @remote_file.exists?('/test/path').should == true
20
+ end
21
+ end
@@ -0,0 +1,5 @@
1
+ require 'rspec'
2
+
3
+ RSpec.configure do |config|
4
+
5
+ end
@@ -0,0 +1 @@
1
+ Test Ruby File
data/spec/thor_test.rb ADDED
@@ -0,0 +1,12 @@
1
+ require 'thor'
2
+ require 'thor-ssh'
3
+
4
+
5
+ class ThorTest < Thor
6
+ include Thor::Actions
7
+ include ThorSsh::Actions
8
+
9
+ def self.source_root
10
+ File.dirname(__FILE__)
11
+ end
12
+ end
@@ -0,0 +1 @@
1
+ {"active":{"default":"11f0dbac-afd7-43ce-b6d8-7c10268c68f7"}}
@@ -0,0 +1,99 @@
1
+ # -*- mode: ruby -*-
2
+ # vi: set ft=ruby :
3
+
4
+ Vagrant::Config.run do |config|
5
+ # All Vagrant configuration is done here. The most common configuration
6
+ # options are documented and commented below. For a complete reference,
7
+ # please see the online documentation at vagrantup.com.
8
+
9
+ # Every Vagrant virtual environment requires a box to build off of.
10
+ config.vm.box = "ubuntu11"
11
+
12
+ # The url from where the 'config.vm.box' box will be fetched if it
13
+ # doesn't already exist on the user's system.
14
+ # config.vm.box_url = "http://domain.com/path/to/above.box"
15
+
16
+ # Boot with a GUI so you can see the screen. (Default is headless)
17
+ # config.vm.boot_mode = :gui
18
+
19
+ # Assign this VM to a host-only network IP, allowing you to access it
20
+ # via the IP. Host-only networks can talk to the host machine as well as
21
+ # any other machines on the same network, but cannot be accessed (through this
22
+ # network interface) by any external networks.
23
+ # config.vm.network :hostonly, "192.168.33.10"
24
+
25
+ # Assign this VM to a bridged network, allowing you to connect directly to a
26
+ # network using the host's network device. This makes the VM appear as another
27
+ # physical device on your network.
28
+ # config.vm.network :bridged
29
+
30
+ # Forward a port from the guest to the host, which allows for outside
31
+ # computers to access the VM, whereas host only networking does not.
32
+ # config.vm.forward_port 80, 8080
33
+
34
+ # Share an additional folder to the guest VM. The first argument is
35
+ # an identifier, the second is the path on the guest to mount the
36
+ # folder, and the third is the path on the host to the actual folder.
37
+ # config.vm.share_folder "v-data", "/vagrant_data", "../data"
38
+
39
+ # Enable provisioning with Puppet stand alone. Puppet manifests
40
+ # are contained in a directory path relative to this Vagrantfile.
41
+ # You will need to create the manifests directory and a manifest in
42
+ # the file ubuntu11.pp in the manifests_path directory.
43
+ #
44
+ # An example Puppet manifest to provision the message of the day:
45
+ #
46
+ # # group { "puppet":
47
+ # # ensure => "present",
48
+ # # }
49
+ # #
50
+ # # File { owner => 0, group => 0, mode => 0644 }
51
+ # #
52
+ # # file { '/etc/motd':
53
+ # # content => "Welcome to your Vagrant-built virtual machine!
54
+ # # Managed by Puppet.\n"
55
+ # # }
56
+ #
57
+ # config.vm.provision :puppet do |puppet|
58
+ # puppet.manifests_path = "manifests"
59
+ # puppet.manifest_file = "ubuntu11.pp"
60
+ # end
61
+
62
+ # Enable provisioning with chef solo, specifying a cookbooks path, roles
63
+ # path, and data_bags path (all relative to this Vagrantfile), and adding
64
+ # some recipes and/or roles.
65
+ #
66
+ # config.vm.provision :chef_solo do |chef|
67
+ # chef.cookbooks_path = "../my-recipes/cookbooks"
68
+ # chef.roles_path = "../my-recipes/roles"
69
+ # chef.data_bags_path = "../my-recipes/data_bags"
70
+ # chef.add_recipe "mysql"
71
+ # chef.add_role "web"
72
+ #
73
+ # # You may also specify custom JSON attributes:
74
+ # chef.json = { :mysql_password => "foo" }
75
+ # end
76
+
77
+ # Enable provisioning with chef server, specifying the chef server URL,
78
+ # and the path to the validation key (relative to this Vagrantfile).
79
+ #
80
+ # The Opscode Platform uses HTTPS. Substitute your organization for
81
+ # ORGNAME in the URL and validation key.
82
+ #
83
+ # If you have your own Chef Server, use the appropriate URL, which may be
84
+ # HTTP instead of HTTPS depending on your configuration. Also change the
85
+ # validation key to validation.pem.
86
+ #
87
+ # config.vm.provision :chef_client do |chef|
88
+ # chef.chef_server_url = "https://api.opscode.com/organizations/ORGNAME"
89
+ # chef.validation_key_path = "ORGNAME-validator.pem"
90
+ # end
91
+ #
92
+ # If you're using the Opscode platform, your validator client is
93
+ # ORGNAME-validator, replacing ORGNAME with your organization name.
94
+ #
95
+ # IF you have your own Chef Server, the default validation client name is
96
+ # chef-validator, unless you changed the configuration.
97
+ #
98
+ # chef.validation_client_name = "ORGNAME-validator"
99
+ end
@@ -0,0 +1,29 @@
1
+ require 'vagrant'
2
+ require 'net/ssh'
3
+
4
+ # Return an ssh connection
5
+ class VagrantManager
6
+ def self.connect
7
+ @vm = Vagrant::Environment.new(:cwd => File.dirname(__FILE__)).primary_vm
8
+
9
+ ssh_info = @vm.ssh.info
10
+
11
+ # Build the options we'll use to initiate the connection via Net::SSH
12
+ opts = {
13
+ :port => ssh_info[:port],
14
+ :keys => [ssh_info[:private_key_path]],
15
+ :keys_only => true,
16
+ :user_known_hosts_file => [],
17
+ :paranoid => false,
18
+ :config => false,
19
+ :forward_agent => ssh_info[:forward_agent]
20
+ }
21
+
22
+ # Check that the private key permissions are valid
23
+ @vm.ssh.check_key_permissions(ssh_info[:private_key_path])
24
+
25
+ # Connect to SSH, giving it a few tries
26
+ return Net::SSH.start(ssh_info[:host], ssh_info[:username], opts)
27
+ end
28
+ end
29
+
data/thor-ssh.gemspec ADDED
@@ -0,0 +1,26 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/thor-ssh/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["Ryan Stout"]
6
+ gem.email = ["ryanstout@gmail.com"]
7
+ gem.description = %q{Makes it so you can set a remote destination for thor's actions (via ssh/sftp)}
8
+ gem.summary = %q{Makes thor work with remote destinations}
9
+ gem.homepage = "https://github.com/ryanstout/thor-ssh"
10
+
11
+ gem.files = `git ls-files`.split($\)
12
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
13
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
14
+ gem.name = "thor-ssh"
15
+ gem.require_paths = ["lib"]
16
+ gem.add_runtime_dependency 'thor', '~> 0.15.2'
17
+ gem.add_runtime_dependency 'net-ssh', '= 2.2.2'
18
+ gem.add_runtime_dependency 'net-sftp', '= 2.0.5'
19
+ gem.add_development_dependency 'rspec', '~> 2.10'
20
+ gem.add_development_dependency 'vagrant', '= 1.0.3'
21
+ gem.add_development_dependency 'rake', '~> 0.9'
22
+ gem.add_development_dependency 'rdoc', '~> 3.9'
23
+ gem.rdoc_options = ['--charset=UTF-8']
24
+
25
+ gem.version = ThorSsh::VERSION
26
+ end
metadata ADDED
@@ -0,0 +1,196 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: thor-ssh
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.8
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Ryan Stout
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-05-19 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: thor
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 0.15.2
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: 0.15.2
30
+ - !ruby/object:Gem::Dependency
31
+ name: net-ssh
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - '='
36
+ - !ruby/object:Gem::Version
37
+ version: 2.2.2
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - '='
44
+ - !ruby/object:Gem::Version
45
+ version: 2.2.2
46
+ - !ruby/object:Gem::Dependency
47
+ name: net-sftp
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - '='
52
+ - !ruby/object:Gem::Version
53
+ version: 2.0.5
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - '='
60
+ - !ruby/object:Gem::Version
61
+ version: 2.0.5
62
+ - !ruby/object:Gem::Dependency
63
+ name: rspec
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ~>
68
+ - !ruby/object:Gem::Version
69
+ version: '2.10'
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ~>
76
+ - !ruby/object:Gem::Version
77
+ version: '2.10'
78
+ - !ruby/object:Gem::Dependency
79
+ name: vagrant
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - '='
84
+ - !ruby/object:Gem::Version
85
+ version: 1.0.3
86
+ type: :development
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - '='
92
+ - !ruby/object:Gem::Version
93
+ version: 1.0.3
94
+ - !ruby/object:Gem::Dependency
95
+ name: rake
96
+ requirement: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ~>
100
+ - !ruby/object:Gem::Version
101
+ version: '0.9'
102
+ type: :development
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ~>
108
+ - !ruby/object:Gem::Version
109
+ version: '0.9'
110
+ - !ruby/object:Gem::Dependency
111
+ name: rdoc
112
+ requirement: !ruby/object:Gem::Requirement
113
+ none: false
114
+ requirements:
115
+ - - ~>
116
+ - !ruby/object:Gem::Version
117
+ version: '3.9'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ none: false
122
+ requirements:
123
+ - - ~>
124
+ - !ruby/object:Gem::Version
125
+ version: '3.9'
126
+ description: Makes it so you can set a remote destination for thor's actions (via
127
+ ssh/sftp)
128
+ email:
129
+ - ryanstout@gmail.com
130
+ executables: []
131
+ extensions: []
132
+ extra_rdoc_files: []
133
+ files:
134
+ - .gitignore
135
+ - Gemfile
136
+ - LICENSE
137
+ - README.md
138
+ - Rakefile
139
+ - lib/thor-ssh.rb
140
+ - lib/thor-ssh/actions.rb
141
+ - lib/thor-ssh/actions/create_file.rb
142
+ - lib/thor-ssh/actions/create_link.rb
143
+ - lib/thor-ssh/actions/empty_directory.rb
144
+ - lib/thor-ssh/actions/file_manipulation.rb
145
+ - lib/thor-ssh/actions/inject_into_file.rb
146
+ - lib/thor-ssh/remote_file.rb
147
+ - lib/thor-ssh/version.rb
148
+ - spec/actions_spec.rb
149
+ - spec/remote_file_spec.rb
150
+ - spec/spec_helper.rb
151
+ - spec/templates/test_template.rb.tt
152
+ - spec/thor_test.rb
153
+ - spec/vagrant/.vagrant
154
+ - spec/vagrant/Vagrantfile
155
+ - spec/vagrant/vagrant_manager.rb
156
+ - thor-ssh.gemspec
157
+ homepage: https://github.com/ryanstout/thor-ssh
158
+ licenses: []
159
+ post_install_message:
160
+ rdoc_options:
161
+ - --charset=UTF-8
162
+ require_paths:
163
+ - lib
164
+ required_ruby_version: !ruby/object:Gem::Requirement
165
+ none: false
166
+ requirements:
167
+ - - ! '>='
168
+ - !ruby/object:Gem::Version
169
+ version: '0'
170
+ segments:
171
+ - 0
172
+ hash: -1300273360678236015
173
+ required_rubygems_version: !ruby/object:Gem::Requirement
174
+ none: false
175
+ requirements:
176
+ - - ! '>='
177
+ - !ruby/object:Gem::Version
178
+ version: '0'
179
+ segments:
180
+ - 0
181
+ hash: -1300273360678236015
182
+ requirements: []
183
+ rubyforge_project:
184
+ rubygems_version: 1.8.22
185
+ signing_key:
186
+ specification_version: 3
187
+ summary: Makes thor work with remote destinations
188
+ test_files:
189
+ - spec/actions_spec.rb
190
+ - spec/remote_file_spec.rb
191
+ - spec/spec_helper.rb
192
+ - spec/templates/test_template.rb.tt
193
+ - spec/thor_test.rb
194
+ - spec/vagrant/.vagrant
195
+ - spec/vagrant/Vagrantfile
196
+ - spec/vagrant/vagrant_manager.rb