nanoc-sftp 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/.document ADDED
@@ -0,0 +1,4 @@
1
+ lib/**/*.rb
2
+ README.rdoc
3
+ ChangeLog.rdoc
4
+ LICENSE.txt
data/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ Gemfile.lock
2
+ html/
3
+ pkg/
4
+ vendor/cache/*.gem
data/ChangeLog ADDED
@@ -0,0 +1,9 @@
1
+ 2012-09-21 pdkl95 <pdkl95@thoughtnoise.net>
2
+
3
+ * First public release
4
+ * Version bump: 1.0.0
5
+
6
+ 2012-09-07 pdkl95 <pdkl95@thoughtnoise.net>
7
+
8
+ * Initial project creation
9
+
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source :rubygems
2
+
3
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2012 Brent Sanders
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.markdown ADDED
@@ -0,0 +1,128 @@
1
+ nanoc-sftp
2
+ ===========
3
+
4
+ A deploy script for [nanoc](http://nanoc.stoneship.org/),
5
+ that uses only SFTP to talk to the server.
6
+
7
+ **NOTE:** this is unfinished, and currently requires you to have
8
+ [yad](http://code.google.com/p/yad/) installed for some things
9
+ that will hopefully be made optional in the future.
10
+
11
+
12
+ Installation
13
+ ------------
14
+
15
+ Add this line to your application's Gemfile:
16
+
17
+ ```bash
18
+ gem 'nanoc-sftp'
19
+ ```
20
+
21
+ And then run:
22
+
23
+ ```bash
24
+ bundle
25
+ ```
26
+
27
+ Or install it yourself with:
28
+
29
+ ```bash
30
+ gem install nanoc-sftp
31
+ ```
32
+
33
+ Usage
34
+ -----
35
+
36
+ This is still broken, due to what may be a bug in nanoc.
37
+ Currently, the only way to guarantee that this gem is loaded
38
+ soon enough is to patch one of the loaders for the `nanoc` tool
39
+ itself.
40
+
41
+ For example, if you add the above `gem 'nanoc-sftp'` line to your
42
+ `Gemfile`, run the gem bundler to install local binstubs:
43
+
44
+ ```bash
45
+ gem install --binstubs
46
+ ```
47
+
48
+ Then, patch the file `bin/nanoc` to include the line
49
+ 'require 'nanoc/sftp'` **before** the main program is loaded. For
50
+ example, it should end up looking something like this:
51
+
52
+ ```ruby
53
+ require 'pathname'
54
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
55
+ Pathname.new(__FILE__).realpath)
56
+
57
+ require 'rubygems'
58
+ require 'bundler/setup'
59
+
60
+ require 'nanoc'
61
+ require 'nanoc/sftp'
62
+
63
+ load Gem.bin_path('nanoc', 'nanoc')
64
+ ```
65
+
66
+ Then, you will need to run nanoc through both this binstub loader AND
67
+ the bunder environment:
68
+
69
+ ```bash
70
+ bundle exec ./bin/nanoc deploy --target staging
71
+ ```
72
+
73
+ For the moment, I suggest setting up a simple alias in your shell
74
+ to wrap this up. This will create such an alias for you. (you may need
75
+ to modify it slightly if your aliases are not stored in `~/.bash_aliases`
76
+
77
+ ```bash
78
+ echo 'alias nanoc_deploy_staging="bundle exec ./bin/nanoc deploy --target staging"' >> "${HOME}/.bash_aliases"
79
+ ```
80
+
81
+ Hopefully, a better solution will happen soon-ish.
82
+
83
+ Configuration
84
+ -------------
85
+
86
+ The deployment settings are listed in your `config.yaml` file.
87
+ If you wanted to deploy to `myusername@server.example.com`, using
88
+ the non-standard SFTP port `1337`, into the remote directory
89
+ `/foo/bar`, it would look like this:
90
+
91
+ ```yaml
92
+ deploy:
93
+ staging:
94
+ kind: sftp
95
+ user: "myusername"
96
+ host: "server.example.com"
97
+ port: 1337
98
+ path: "/foo/bar"
99
+ ```
100
+
101
+ You can leave out the `port:` line to use the standard
102
+ SFTP port.
103
+
104
+ You will be prompted for the password each time the deploy
105
+ script is found, if the authentication isn't handled automagically
106
+ by a pre-shared key, etc.
107
+
108
+ Requirements
109
+ ------------
110
+
111
+ Because of a personal need, this gem currently relies
112
+ on the utility `[yad](http://code.google.com/p/yad/)` which
113
+ implements a simple GUI.
114
+
115
+ This currently is used to provide a login prompt and a
116
+ verification step before overwriting files. I intend to make
117
+ this optional in the future, but right now it's required
118
+ that the `yad` binary be somewhere in your `$PATH`.
119
+
120
+ Copyright
121
+ ---------
122
+
123
+ Copyright (c) 2012 Brent Sanders
124
+
125
+ See LICENSE.txt for details.
126
+
127
+
128
+
data/Rakefile ADDED
@@ -0,0 +1,40 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rubygems'
4
+
5
+ begin
6
+ require 'bundler'
7
+ rescue LoadError => e
8
+ warn e.message
9
+ warn "Run `gem install bundler` to install Bundler."
10
+ exit -1
11
+ end
12
+
13
+ begin
14
+ Bundler.setup(:development)
15
+ rescue Bundler::BundlerError => e
16
+ warn e.message
17
+ warn "Run `bundle install` to install missing gems."
18
+ exit e.status_code
19
+ end
20
+
21
+ require 'rake'
22
+
23
+ require 'rubygems/tasks'
24
+ class Gem::Tasks::Install
25
+ def install(path)
26
+ run 'gem', 'install', '-q', '--no-rdoc', '--no-ri', path
27
+ end
28
+ end
29
+ task :validate
30
+
31
+ Gem::Tasks.new(:scm => false)
32
+
33
+ #require 'rdoc/task'
34
+ #RDoc::Task.new do |rdoc|
35
+ # rdoc.title = "nanoc-sftp"
36
+ #end
37
+ #task :doc => :rdoc
38
+
39
+
40
+ task :default => :build
@@ -0,0 +1,125 @@
1
+ # encoding: utf-8
2
+
3
+ require 'open3'
4
+ require 'nanoc/sftp/file_sets'
5
+ require 'nanoc/sftp/file_util'
6
+ require 'nanoc/sftp/ui'
7
+ require 'nanoc/sftp/ui/highline'
8
+ require 'nanoc/sftp/ui/yad'
9
+
10
+ module Nanoc::Sftp
11
+ class Deployer < ::Nanoc::Extra::Deployer
12
+ include Nanoc::Sftp::FileSets
13
+ include Nanoc::Sftp::FileUtil
14
+ include Nanoc::Sftp::UI
15
+ include Nanoc::Sftp::UI::Highline
16
+ include Nanoc::Sftp::UI::Yad
17
+
18
+ REQUIRED_FIELDS = [:host, :user, :pass, :path]
19
+ OPTIONAL_FIELDS = [:port, :spinner]
20
+ FIELDS = REQUIRED_FIELDS + OPTIONAL_FIELDS
21
+
22
+ attr_accessor *FIELDS
23
+
24
+ SSL_TRANSPORT_OPTIONS = {
25
+ :compression => true
26
+ }
27
+
28
+ attr_reader :sftp, :srcdir, :topdir, :site
29
+
30
+ def blank?(x)
31
+ x = x.to_s
32
+ x.nil? || x.empty?
33
+ end
34
+
35
+ def initialize(*args)
36
+ super *args
37
+
38
+ FIELDS.each do |field|
39
+ instance_variable_set "@#{field}", config[field].to_s
40
+ end
41
+
42
+ @target = config[:target] || 'staging'
43
+ @target.upcase!
44
+
45
+ @spinner = :fancy if @spinner.nil? || @spinner == ''
46
+ @spinner = @spinner.to_sym if @spinner.is_a? String
47
+
48
+ @srcdir = File.expand_path(self.source_path)
49
+ @topdir = File.expand_path File.join(@srcdir, '/..')
50
+
51
+ Dir.chdir(@topdir) do
52
+ @site = Nanoc::Site.new('.')
53
+ end
54
+ end
55
+
56
+ def run
57
+ require 'net/sftp'
58
+
59
+ stty_backup = `stty -g`
60
+
61
+ Signal.trap("INT") do
62
+ system "stty #{stty_backup}"
63
+ exit(1)
64
+ end
65
+
66
+ deploy!
67
+
68
+ ensure
69
+ system "stty #{stty_backup}"
70
+ end
71
+
72
+ def deploy!
73
+ with_sftp do
74
+ list_existing_files!
75
+ if verify_deploy_plan!
76
+ msg "Deploy plan verified - sending files to #{host} ..."
77
+ deploy_files!
78
+ msg "Finished!"
79
+ else
80
+ msg "*** CANCEL ***"
81
+ msg "Quitting; server remains unchanged!"
82
+ end
83
+ end
84
+ end
85
+
86
+ def list_existing_files!
87
+ list_recursive path do |entry|
88
+ existing_files.add entry
89
+ end
90
+ end
91
+
92
+ def deploy_files!
93
+ msg "Sending *NEW* files..."
94
+ new_files.each do |file|
95
+ upload! file
96
+ end
97
+
98
+ msg "Sending *UPDATED* files..."
99
+ updated_files.each do |file|
100
+ upload! file
101
+ end
102
+
103
+ msg "Removing *STALE* files..."
104
+ stale_files.each do |file|
105
+ expunge! file
106
+ end
107
+ end
108
+
109
+ def missing_required_login_fields?
110
+ REQUIRED_FIELDS.each do |field|
111
+ val = send(field).to_s
112
+ blank?(val) and return true
113
+ end
114
+ false
115
+ end
116
+
117
+ def login_options
118
+ SSL_TRANSPORT_OPTIONS.tap do |opt|
119
+ opt[:password] = @pass
120
+ opt[:port] = @port unless blank? @port
121
+ end
122
+ end
123
+ end
124
+ end
125
+
@@ -0,0 +1,44 @@
1
+ module Nanoc::Sftp
2
+ module FileSets
3
+ def compiled_files_array
4
+ site.items.map do |item|
5
+ item.reps.map do |rep|
6
+ rep.raw_path.sub /^#{self.source_path}\//, ''
7
+ end
8
+ end.flatten.compact.select do |f|
9
+ File.file? "#{self.source_path}/#{f}"
10
+ end
11
+ end
12
+
13
+ def compiled_files
14
+ @compiled_files ||= Set.new compiled_files_array
15
+ end
16
+
17
+ def existing_files
18
+ @existing_files ||= Set.new
19
+ end
20
+
21
+ def updated_files
22
+ @updated_files ||= compiled_files.intersection(existing_files)
23
+ end
24
+
25
+ def new_files
26
+ @new_files ||= compiled_files.difference(updated_files)
27
+ end
28
+
29
+ def stale_files
30
+ @stale_files ||= existing_files.difference(updated_files)
31
+ end
32
+
33
+ def full_changeset
34
+ [].tap do |list|
35
+ list.concat(updated_files.map{ |fn| [fn, :update] })
36
+ list.concat( new_files.map{ |fn| [fn, :new ] })
37
+ list.concat( stale_files.map{ |fn| [fn, :stale ] })
38
+ end.sort do |a,b|
39
+ a.first <=> b.first
40
+ end
41
+ end
42
+ end
43
+ end
44
+
@@ -0,0 +1,104 @@
1
+ module Nanoc::Sftp
2
+ module FileUtil
3
+ def with_sftp(&block)
4
+ ask_for_login_fields if missing_required_login_fields?
5
+ msg "openening a connection to #{user}@#{host}"
6
+ msg "option: #{login_options.inspect}"
7
+ retval = 1
8
+ Net::SFTP.start(host, @user, login_options) do |sftp|
9
+ @sftp = sftp
10
+ retval = block.call
11
+ @sftp = nil
12
+ end
13
+ retval
14
+ end
15
+
16
+ def simulate_upload!(file_path)
17
+ msg = "<dry_run - simulating upload> "
18
+ print msg
19
+
20
+ file_size = File.size(file_path)
21
+ file_mb = file_size.to_f / (2**20).to_f
22
+ min_delay = 0.15
23
+ per_mb = 0.8
24
+ delay = min_delay + (per_mb * file_mb)
25
+ msglen = 1 + msg.length + delay.to_i
26
+ msg_bs = "\b" * msglen
27
+ msg_sp = " " * msglen
28
+ msg_erase = "#{msg_bs}#{msg_sp}#{msg_bs}"
29
+
30
+ while delay > 1.0
31
+ delay -= 1.0
32
+ print "." ; spin 1.0
33
+ end
34
+ print "." ; spin delay
35
+
36
+ print msg_erase
37
+ end
38
+
39
+ def create_remote_directory!(path, dir)
40
+ @created_directories ||= {}
41
+ return if @created_directories[dir]
42
+
43
+ unless sftp.dir[path, dir].first == dir
44
+ fullpath = "#{path}/#{dir}"
45
+ puts "mkdir(#{fullpath.inspect})"
46
+ sftp.mkdir(fullpath)
47
+ end
48
+ @created_directories[dir] = true
49
+ end
50
+
51
+ def upload_file(local_path, remote_path)
52
+ puts "UPLOADING: #{local_path}"
53
+ puts " --> TO: #{remote_path}"
54
+ if self.dry_run?
55
+ simulate_upload!(local_path)
56
+ else
57
+ sftp.upload! local_path, remote_path
58
+ end
59
+ puts "ok"
60
+ end
61
+
62
+ def upload!(file)
63
+ dir = File.dirname(file)
64
+ dirlist = []
65
+ while dir != '.'
66
+ dirlist.push(dir)
67
+ dir = File.dirname(dir)
68
+ end
69
+ while dirlist.length > 0
70
+ create_remote_directory! path, dirlist.pop
71
+ end
72
+ upload_file "#{srcdir}/#{file}", "#{path}/#{file}"
73
+ end
74
+
75
+ def expunge!(file)
76
+ dst = "#{path}/#{file}"
77
+ puts "EXPUNGING: #{dst.inspect}"
78
+ sftp.remove!(dst)
79
+ end
80
+
81
+ def skip_entry?(entry)
82
+ entry.directory? ||
83
+ entry.name.start_with?('.')
84
+ end
85
+
86
+ def filtered_yield(enum)
87
+ enum.each do |entry|
88
+ yield entry.name unless skip_entry? entry
89
+ end
90
+ end
91
+
92
+ def list(dir, &block)
93
+ filtered_yield sftp.dir.foreach(dir).to_enum, &block
94
+ end
95
+
96
+ def glob(*args, &block)
97
+ filtered_yield sftp.dir.glob(*args).to_enum, &block
98
+ end
99
+
100
+ def list_recursive(dir, &block)
101
+ glob dir, "**/*", &block
102
+ end
103
+ end
104
+ end
@@ -0,0 +1,54 @@
1
+ module Nanoc::Sftp::UI
2
+ module Highline
3
+ def load_highline_if_possible
4
+ require 'highline/import'
5
+ @have_hl = true
6
+ rescue LoadError
7
+ @have_hl = false
8
+ end
9
+
10
+ def have_highline?
11
+ load_highline_if_possible unless defined? @have_hl
12
+ puts "Have highline: #{@have_hl}"
13
+ @have_hl
14
+ end
15
+
16
+ def ask_for_login_fields_with_highline
17
+ @host = ask("What is the <%= color('hostname', BOLD) %> " +
18
+ "of the SFTP server?\n"
19
+ ) { |q|
20
+ q.default = @host
21
+ q.validate = /^(([a-zA-Z]|[a-zA-Z][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z]|[A-Za-z][A-Za-z0-9\-]*[A-Za-z0-9])$/
22
+
23
+ q.whitespace = :remove
24
+ }
25
+
26
+ @post = ask("What <%= color('Port') %> is the SFTP server using? ",
27
+ "(leave it blank to use the standard port, 22/tcp)"
28
+ ) { |q|
29
+ q.default = @port.to_s
30
+ q.whitespace = :remove
31
+ q.validate = /^\d{2,5}$/
32
+ }
33
+
34
+ @user = ask("What <%= color('username') %> to login as? "
35
+ ) { |q|
36
+ q.default = @user
37
+ q.whitespace = :strip
38
+ q.validate = /^\w+$/
39
+ }
40
+
41
+ @pass = ask("Please enter your <%= color('password', BOLD) %> now,\n" +
42
+ "to login with SFTP \"<%= color('#{@user}', BOLD) %>" +
43
+ "@<%= color('#{@host}', BOLD) %>:<%= color('#{@port}', BOLD) %>\":"
44
+ ) { |q|
45
+ q.echo = false
46
+ q.whitespace = nil
47
+ }
48
+ end
49
+
50
+ def verify_with_highline
51
+ raise "FIXME"
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,129 @@
1
+ require 'pp'
2
+
3
+ module Nanoc::Sftp::UI
4
+ module Yad
5
+ def have_yad?
6
+ if @yad.nil? ; then
7
+ ENV['PATH'].split(/:/).each do |dir|
8
+ file = "#{dir}/yad"
9
+ if File.executable?(file)
10
+ @yad = file
11
+ return @yad
12
+ end
13
+ end
14
+ false
15
+ else
16
+ @yad
17
+ end
18
+ end
19
+
20
+ def verify_deploy_plan_yad!
21
+ text = "<span size='x-large'>Deployment Plan</span>\n<span>Sould the following changes be made on the server?</span>"
22
+ args = [
23
+ "--list",
24
+ "--column=CHK:CHK",
25
+ "--column=@back@",
26
+ "--column=IMG:IMG",
27
+ "--column=Status:TEXT",
28
+ "--column=TIP:TIP",
29
+ "--column=File:TEXT",
30
+ "--hide-column=5",
31
+ "--search-column=6",
32
+ "--checklist",
33
+ "--print-all",
34
+ "--title=Deployment Plan",
35
+ "--image=upload-media",
36
+ "--window-icon=upload-media",
37
+ # "--no-headers",
38
+ "--width=600",
39
+ "--height=400",
40
+ "--image-on-top",
41
+ "--text=#{text}",
42
+ "--buttons-layout=spread",
43
+ "--button=gtk-execute:0",
44
+ "--button=gtk-cancel:1",
45
+ "--borders=3"
46
+ ]
47
+ cmd = args.map { |x| "\"#{x}\"" }.join(' ')
48
+ cmd = "#{@yad} #{cmd}"
49
+
50
+ Open3.popen3(cmd) do |stdin,stdout,stderr,wait_thr|
51
+ stdin.write(full_changeset.map do |x|
52
+ fn, status = *x
53
+ case status
54
+ when :new then ['TRUE', '#CCFFD1', 'gtk-new', 'NEW', "creates: #{path}/#{fn}"]
55
+ when :update then ['TRUE', '#FFD0D2', 'gtk-save-as', 'UPDATE', "updates: #{path}/#{fn} with #{srcdir}/#{fn}"]
56
+ when :stale then ['FALSE', '#FFF899', 'gtk-delete', 'STALE', "removes: #{path}/#{fn}"]
57
+ else raise "unknown status: #{status}"
58
+ end.concat(["#{fn}"])
59
+ end.flatten.join("\n"))
60
+ stdin.flush
61
+ stdin.close
62
+ @plan = stdout.readlines.map do |line|
63
+ Hash[ [:ok, :bgcolor, :status, :tooltip, :file].zip line.split(/\|/) ]
64
+ end
65
+ @success = wait_thr.value.success?
66
+ end
67
+
68
+ if @success
69
+ @plan.each do |x|
70
+ if x[:ok] == 'FALSE'
71
+ case x[:status]
72
+ when 'NEW' then new_files
73
+ when 'UPDATE' then updated_files
74
+ when 'STALE' then stale_files
75
+ else raise "bad status value: #{x[:status]}"
76
+ end.delete x[:file]
77
+ end
78
+ end
79
+ end
80
+
81
+ end
82
+
83
+ def ask_for_login_fields_with_yad
84
+ dialog_text = [
85
+ '<span size="large">',
86
+ 'Deploying to the ',
87
+ '<span font-weight="bold" foreground="#c24545">',
88
+ @target,
89
+ '</span> server</span>'
90
+ ].join('')
91
+
92
+ args = [
93
+ "--form",
94
+ "--buttons-layout=edge",
95
+ "--button=gtk-apply:0",
96
+ "--button=gtk-cancel:1",
97
+ "--on-load",
98
+ "--borders=5",
99
+ "--text=#{dialog_text}",
100
+ "--title=Deploying website to the #{@target} server",
101
+ "--image=upload-media",
102
+ "--window-icon=upload-media",
103
+ "--align=right",
104
+ "--columns=2",
105
+ "--separator=|",
106
+ "--field=Hostname",
107
+ "--field=Port:NUM",
108
+ "--field=Username",
109
+ "--field=Password:H",
110
+ "thoughtnoise.net",
111
+ "2501!22..65535!1!0",
112
+ "telleena",
113
+ "" # empty pass
114
+ ]
115
+ cmd = args.map { |x| "'#{x}'" }.join(' ')
116
+ cmd = "#{@yad} #{cmd}"
117
+
118
+ output = IO.popen(cmd, 'r') do |prog|
119
+ prog.read.split(/\|/)
120
+ end
121
+ ret = $?.to_i
122
+
123
+ @host = output[0]
124
+ @port = output[1].to_i
125
+ @user = output[2]
126
+ @pass = output[3]
127
+ end
128
+ end
129
+ end
@@ -0,0 +1,47 @@
1
+ # encoding: utf-8
2
+
3
+ module Nanoc::Sftp
4
+ module UI
5
+ SPIN = {
6
+ :basic => "\\|/-",
7
+ # :fancy => "▟▄▙▌▛▀▜▐"
8
+ :fancy => "\u259F\u2584\u2599\u258C\u259B\u2580\u259C\u2590"
9
+ }
10
+
11
+ def spin(n, style = spinner)
12
+ @spinval ||= 0
13
+ print '* '
14
+ while n > 0.1
15
+ @spinval += 1
16
+ @spinval = 0 if @spinval >= SPIN[style].length
17
+ c = SPIN[style][@spinval,1]
18
+ print "\b\b#{c} "
19
+ sleep 0.1
20
+ n -= 0.1
21
+ end
22
+ print "\b\b \b\b"
23
+ sleep n
24
+ end
25
+
26
+ def msg(*args)
27
+ msg = args.flatten.join(' ')
28
+ puts "[nanoc-sftp] #{msg}"
29
+ end
30
+
31
+ def ask_for_login_fields
32
+ if have_yad?
33
+ ask_for_login_fields_with_yad
34
+ else
35
+ raise "no yad?"
36
+ end
37
+ end
38
+
39
+ def verify_deploy_plan!
40
+ if have_yad?
41
+ return verify_deploy_plan_yad!
42
+ else
43
+ raise "no yad?"
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,8 @@
1
+ module Nanoc
2
+ module Sftp
3
+ VERSION_MAJOR = 1
4
+ VERSION_MINOR = 0
5
+ VERSION_TINY = 0
6
+ VERSION = [VERSION_MAJOR, VERSION_MINOR, VERSION_TINY].join('.')
7
+ end
8
+ end
data/lib/nanoc/sftp.rb ADDED
@@ -0,0 +1,8 @@
1
+ require 'nanoc'
2
+
3
+ module Nanoc
4
+ module Sftp
5
+ autoload 'Deployer', 'nanoc/sftp/deployer'
6
+ Nanoc::Extra::Deployer.register '::Nanoc::Sftp::Deployer', :sftp
7
+ end
8
+ end
@@ -0,0 +1,27 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ require File.expand_path('../lib/nanoc/sftp/version', __FILE__)
4
+
5
+ Gem::Specification.new do |gem|
6
+ gem.name = "nanoc-sftp"
7
+ gem.version = Nanoc::Sftp::VERSION
8
+ gem.summary = %q{Nanoc deploy plugin For places where a full SSH login is disabled, but simple chroot-jail SFTP is allowed. The stock rsync method is recommended over this, if possible.}
9
+ gem.description = %q{An SFTP-only deploy script for nanoc}
10
+ gem.license = "MIT"
11
+ gem.authors = ["Brent Sanders"]
12
+ gem.email = "git@thoughtnoise.net"
13
+ gem.homepage = "http://github.dom/pdkl95/nanoc-sftp"
14
+
15
+ gem.files = `git ls-files`.split($/)
16
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
+ gem.require_paths = ['lib']
19
+
20
+ gem.add_dependency "net-sftp", "~> 2.0"
21
+ #gem.add_dependency "highline", "~> 1.6"
22
+
23
+ gem.add_development_dependency 'bundler', '~> 1.0'
24
+ gem.add_development_dependency 'rake', '~> 0.8'
25
+ #gem.add_development_dependency 'rdoc', '~> 3.0'
26
+ gem.add_development_dependency 'rubygems-tasks', '~> 0.2'
27
+ end
metadata ADDED
@@ -0,0 +1,130 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: nanoc-sftp
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Brent Sanders
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-09-21 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: net-sftp
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '2.0'
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: '2.0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: bundler
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ~>
36
+ - !ruby/object:Gem::Version
37
+ version: '1.0'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: '1.0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: rake
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ~>
52
+ - !ruby/object:Gem::Version
53
+ version: '0.8'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: '0.8'
62
+ - !ruby/object:Gem::Dependency
63
+ name: rubygems-tasks
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ~>
68
+ - !ruby/object:Gem::Version
69
+ version: '0.2'
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: '0.2'
78
+ description: An SFTP-only deploy script for nanoc
79
+ email: git@thoughtnoise.net
80
+ executables: []
81
+ extensions: []
82
+ extra_rdoc_files: []
83
+ files:
84
+ - .document
85
+ - .gitignore
86
+ - ChangeLog
87
+ - Gemfile
88
+ - LICENSE.txt
89
+ - README.markdown
90
+ - Rakefile
91
+ - lib/nanoc/sftp.rb
92
+ - lib/nanoc/sftp/deployer.rb
93
+ - lib/nanoc/sftp/file_sets.rb
94
+ - lib/nanoc/sftp/file_util.rb
95
+ - lib/nanoc/sftp/ui.rb
96
+ - lib/nanoc/sftp/ui/highline.rb
97
+ - lib/nanoc/sftp/ui/yad.rb
98
+ - lib/nanoc/sftp/version.rb
99
+ - nanoc-sftp.gemspec
100
+ homepage: http://github.dom/pdkl95/nanoc-sftp
101
+ licenses:
102
+ - MIT
103
+ post_install_message:
104
+ rdoc_options: []
105
+ require_paths:
106
+ - lib
107
+ required_ruby_version: !ruby/object:Gem::Requirement
108
+ none: false
109
+ requirements:
110
+ - - ! '>='
111
+ - !ruby/object:Gem::Version
112
+ version: '0'
113
+ segments:
114
+ - 0
115
+ hash: 1725721838413355219
116
+ required_rubygems_version: !ruby/object:Gem::Requirement
117
+ none: false
118
+ requirements:
119
+ - - ! '>='
120
+ - !ruby/object:Gem::Version
121
+ version: '0'
122
+ requirements: []
123
+ rubyforge_project:
124
+ rubygems_version: 1.8.24
125
+ signing_key:
126
+ specification_version: 3
127
+ summary: Nanoc deploy plugin For places where a full SSH login is disabled, but simple
128
+ chroot-jail SFTP is allowed. The stock rsync method is recommended over this, if
129
+ possible.
130
+ test_files: []