sprout 0.7.153-darwin
Sign up to get free protection for your applications and to get access to all the features.
- data/MIT-LICENSE +20 -0
- data/TODO +12 -0
- data/bin/sprout +128 -0
- data/doc/Bundle +14 -0
- data/doc/Generator +35 -0
- data/doc/Library +63 -0
- data/doc/Task +21 -0
- data/doc/Tool +20 -0
- data/lib/platform.rb +109 -0
- data/lib/progress_bar.rb +330 -0
- data/lib/sprout.rb +456 -0
- data/lib/sprout/builder.rb +35 -0
- data/lib/sprout/commands/generate.rb +14 -0
- data/lib/sprout/general_tasks.rb +5 -0
- data/lib/sprout/generator.rb +6 -0
- data/lib/sprout/generator/base_mixins.rb +132 -0
- data/lib/sprout/generator/named_base.rb +216 -0
- data/lib/sprout/log.rb +46 -0
- data/lib/sprout/process_runner.rb +46 -0
- data/lib/sprout/project_model.rb +114 -0
- data/lib/sprout/remote_file_loader.rb +233 -0
- data/lib/sprout/remote_file_target.rb +96 -0
- data/lib/sprout/simple_resolver.rb +88 -0
- data/lib/sprout/tasks/gem_wrap_task.rb +192 -0
- data/lib/sprout/tasks/library_task.rb +103 -0
- data/lib/sprout/tasks/sftp_task.rb +245 -0
- data/lib/sprout/tasks/tool_task.rb +541 -0
- data/lib/sprout/tasks/zip_task.rb +158 -0
- data/lib/sprout/template_resolver.rb +207 -0
- data/lib/sprout/user.rb +359 -0
- data/lib/sprout/version.rb +10 -0
- data/lib/sprout/zip_util.rb +61 -0
- data/rakefile.rb +129 -0
- data/samples/gem_wrap/rakefile.rb +17 -0
- metadata +159 -0
@@ -0,0 +1,88 @@
|
|
1
|
+
=begin
|
2
|
+
Copyright (c) 2007 Pattern Park
|
3
|
+
|
4
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
5
|
+
a copy of this software and associated documentation files (the
|
6
|
+
"Software"), to deal in the Software without restriction, including
|
7
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
8
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
9
|
+
permit persons to whom the Software is furnished to do so, subject to
|
10
|
+
the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be
|
13
|
+
included in all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
17
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
19
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
20
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
21
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
22
|
+
=end
|
23
|
+
require 'erb'
|
24
|
+
|
25
|
+
module Sprout
|
26
|
+
|
27
|
+
class SimpleResolver #:nodoc:
|
28
|
+
|
29
|
+
def initialize(template, output, files, base_dir=nil)
|
30
|
+
@template = template
|
31
|
+
@output = output
|
32
|
+
@files = files
|
33
|
+
@base_dir = base_dir
|
34
|
+
@ignored_files = []
|
35
|
+
execute
|
36
|
+
finish
|
37
|
+
end
|
38
|
+
|
39
|
+
def execute
|
40
|
+
template_file = File.open(@template, 'r')
|
41
|
+
content = template_file.read
|
42
|
+
result = ERB.new(content, nil, '>').result(binding)
|
43
|
+
|
44
|
+
output_file = File.open(@output, 'w')
|
45
|
+
output_file.write(result)
|
46
|
+
|
47
|
+
template_file.close
|
48
|
+
output_file.close
|
49
|
+
end
|
50
|
+
|
51
|
+
def files
|
52
|
+
return @files
|
53
|
+
end
|
54
|
+
|
55
|
+
def finish
|
56
|
+
if(@ignored_files.size > 0)
|
57
|
+
Logger.puts '>> SimpleResolver ignored the following files because their names were invalid:'
|
58
|
+
@ignored_files.each do |file|
|
59
|
+
puts file
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def xml_edit_warning
|
65
|
+
return <<EOF
|
66
|
+
<!--
|
67
|
+
DO NOT EDIT THIS FILE!
|
68
|
+
This file was auto-generated from
|
69
|
+
an ERB template which can be
|
70
|
+
found at:
|
71
|
+
#{@template}
|
72
|
+
-->
|
73
|
+
EOF
|
74
|
+
end
|
75
|
+
|
76
|
+
def edit_warning
|
77
|
+
return <<EOF
|
78
|
+
/*************************************
|
79
|
+
* DO NOT EDIT THIS FILE!
|
80
|
+
* This file was auto-generated from
|
81
|
+
* an ERB template which can be
|
82
|
+
* found at:
|
83
|
+
* #{@template}
|
84
|
+
*************************************/
|
85
|
+
EOF
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,192 @@
|
|
1
|
+
=begin
|
2
|
+
Copyright (c) 2007 Pattern Park
|
3
|
+
|
4
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
5
|
+
a copy of this software and associated documentation files (the
|
6
|
+
"Software"), to deal in the Software without restriction, including
|
7
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
8
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
9
|
+
permit persons to whom the Software is furnished to do so, subject to
|
10
|
+
the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be
|
13
|
+
included in all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
17
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
19
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
20
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
21
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
22
|
+
|
23
|
+
TODO: Update mxmlc task
|
24
|
+
* Update mxmlc to include all advanced options
|
25
|
+
* Clean up default values
|
26
|
+
* Investigate jruby support, especially:
|
27
|
+
http://livedocs.adobe.com/flex/201/html/wwhelp/wwhimpl/common/html/wwhelp.htm?context=LiveDocs_Book_Parts&file=compilers_123_09.html
|
28
|
+
=end
|
29
|
+
|
30
|
+
module Sprout
|
31
|
+
class GemWrapError < StandardError #:nodoc:
|
32
|
+
end
|
33
|
+
|
34
|
+
# Creates a ruby gem from a slightly simpler rake task than what gems provides.
|
35
|
+
# Adds support for adding a sprout.spec file to your new gem which is usually useful
|
36
|
+
# for tool or library sprout gems.
|
37
|
+
class GemWrapTask < Rake::Task
|
38
|
+
# The full name of the gem to create like:
|
39
|
+
# t.gem_name = 'sprout-as3-bundle'
|
40
|
+
attr_writer :gem_name
|
41
|
+
# The type of sprout to create, defaults to 'library'
|
42
|
+
# Other possible values are, 'bundle' and 'tool'
|
43
|
+
attr_writer :sprout_type
|
44
|
+
# Full string rubygem version for this sprout, usually in three parts like:
|
45
|
+
# t.version = '0.0.1'
|
46
|
+
attr_writer :version
|
47
|
+
# Folder that the newly-created gem should be placed in
|
48
|
+
attr_writer :package
|
49
|
+
# Summary or short description for the gem
|
50
|
+
attr_writer :summary
|
51
|
+
# The author that created the gem
|
52
|
+
attr_writer :author
|
53
|
+
# Email address for interested users to send questions to
|
54
|
+
attr_writer :email
|
55
|
+
# Homepage where users can learn more about this gem
|
56
|
+
attr_writer :homepage
|
57
|
+
# A string remote file specification usually something like:
|
58
|
+
#
|
59
|
+
# t.sprout_spec =<<EOF
|
60
|
+
# - !ruby/object:Sprout::RemoteFileTarget
|
61
|
+
# platform: universal
|
62
|
+
# url: http://as3flickrlib.googlecode.com/files/flickr-.87.zip
|
63
|
+
# archive_path: flickr-.87/src
|
64
|
+
# EOF
|
65
|
+
attr_writer :sprout_spec
|
66
|
+
|
67
|
+
def self.define_task(args, &block)
|
68
|
+
t = super
|
69
|
+
yield t if block_given?
|
70
|
+
t.define
|
71
|
+
end
|
72
|
+
|
73
|
+
def define # :nodoc:
|
74
|
+
define_gem_name
|
75
|
+
define_extensions(extensions)
|
76
|
+
end
|
77
|
+
|
78
|
+
def initialize(task_name, app) # :nodoc:
|
79
|
+
super
|
80
|
+
@sprout_type = "library"
|
81
|
+
@package = "pkg"
|
82
|
+
@summary = "#{task_name}"
|
83
|
+
@email = "projectsprouts@googlegroups.com"
|
84
|
+
@homepage = "http://www.projectsprouts.org"
|
85
|
+
end
|
86
|
+
|
87
|
+
def execute(*args) # :nodoc:
|
88
|
+
super
|
89
|
+
raise GemWrapError.new("A version must be provided to produce a Gem!") unless @version
|
90
|
+
@summary = "#{name} #{@sprout_type} generated by Sprout::GemWrapTask" unless @summary
|
91
|
+
|
92
|
+
FileUtils.mkdir_p(gem_package)
|
93
|
+
render_sprout_spec(gem_package, @sprout_spec) if @sprout_spec
|
94
|
+
# render_extensions(gem_package, extensions) if extensions.size
|
95
|
+
|
96
|
+
Dir.chdir(gem_package) do
|
97
|
+
|
98
|
+
spec = Gem::Specification.new do |s|
|
99
|
+
files = []
|
100
|
+
s.platform = Gem::Platform::RUBY
|
101
|
+
s.version = @version
|
102
|
+
s.author = @author if @author
|
103
|
+
s.summary = @summary
|
104
|
+
s.name = @gem_name
|
105
|
+
s.email = @email
|
106
|
+
s.homepage = @homepage
|
107
|
+
s.rubyforge_project = 'sprout'
|
108
|
+
s.requirements << {'sprout', '>= 0.7.1'}
|
109
|
+
gem_dependencies.each do |dep|
|
110
|
+
s.requirements << dep
|
111
|
+
end
|
112
|
+
if(File.exists?('sprout.spec'))
|
113
|
+
files << 'sprout.spec'
|
114
|
+
end
|
115
|
+
if(extensions.size > 0)
|
116
|
+
files << 'ext'
|
117
|
+
end
|
118
|
+
zipped_extensions.each do |ext|
|
119
|
+
files << File.join('ext', File.basename(ext))
|
120
|
+
end
|
121
|
+
s.files = files
|
122
|
+
end
|
123
|
+
Gem::Builder.new(spec).build
|
124
|
+
end
|
125
|
+
|
126
|
+
FileUtils.mv("#{gem_package}/#{@gem_name}-#{@version}.gem", @package)
|
127
|
+
FileUtils.rm_rf(gem_package)
|
128
|
+
end
|
129
|
+
|
130
|
+
# Add a gem dependency either with only the gem name
|
131
|
+
# or with a full name and version hash like:
|
132
|
+
#
|
133
|
+
# t.add_dependency('sprout-flashplayer-tool')
|
134
|
+
# or
|
135
|
+
# t.add_dependency('sprout-flashplayer-tool' => '9.115.0')
|
136
|
+
#
|
137
|
+
def add_dependency(args)
|
138
|
+
gem_dependencies << args
|
139
|
+
end
|
140
|
+
|
141
|
+
def gem_dependencies
|
142
|
+
return @gem_dependencies ||= []
|
143
|
+
end
|
144
|
+
|
145
|
+
# Add files to include in the gem/ext folder
|
146
|
+
def extensions
|
147
|
+
return @extensions ||= []
|
148
|
+
end
|
149
|
+
|
150
|
+
private
|
151
|
+
|
152
|
+
def gem_package
|
153
|
+
@gem_package ||= File.join(@package, @gem_name)
|
154
|
+
end
|
155
|
+
|
156
|
+
def zipped_extensions
|
157
|
+
return @zipped_extensions ||= []
|
158
|
+
end
|
159
|
+
|
160
|
+
def define_gem_name
|
161
|
+
@gem_name = "sprout-#{name}-#{@sprout_type}" if !@gem_name
|
162
|
+
end
|
163
|
+
|
164
|
+
def define_extensions(exts)
|
165
|
+
exts.each do |ext|
|
166
|
+
if(File.directory?(ext))
|
167
|
+
full = File.expand_path(ext)
|
168
|
+
t = nil
|
169
|
+
|
170
|
+
zip full do |t|
|
171
|
+
t.input = full
|
172
|
+
t.output = File.join(gem_name, 'ext', File.basename(full) + '.zip')
|
173
|
+
end
|
174
|
+
puts "pwd: #{Dir.pwd} out #{t.output}"
|
175
|
+
zipped_extensions << File.expand_path(t.output)
|
176
|
+
prerequisites << t.output
|
177
|
+
end
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
def render_sprout_spec(target, spec)
|
182
|
+
File.open(File.join(target, 'sprout.spec'), 'w') do |f|
|
183
|
+
f.write(spec)
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
def gem_wrap(args, &block)
|
191
|
+
Sprout::GemWrapTask.define_task(args, &block)
|
192
|
+
end
|
@@ -0,0 +1,103 @@
|
|
1
|
+
=begin
|
2
|
+
Copyright (c) 2007 Pattern Park
|
3
|
+
|
4
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
5
|
+
a copy of this software and associated documentation files (the
|
6
|
+
"Software"), to deal in the Software without restriction, including
|
7
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
8
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
9
|
+
permit persons to whom the Software is furnished to do so, subject to
|
10
|
+
the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be
|
13
|
+
included in all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
17
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
19
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
20
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
21
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
22
|
+
=end
|
23
|
+
|
24
|
+
module Sprout
|
25
|
+
class LibraryError < StandardError #:nodoc:
|
26
|
+
end
|
27
|
+
|
28
|
+
# :include: ../../../doc/Library
|
29
|
+
class LibraryTask < Rake::Task
|
30
|
+
|
31
|
+
# The RubyGems gem version string for this library (e.g., +version = '0.0.1'+)
|
32
|
+
attr_accessor :version
|
33
|
+
|
34
|
+
attr_writer :gem_name # :nodoc:
|
35
|
+
attr_writer :project_lib # :nodoc:
|
36
|
+
|
37
|
+
def self.define_task(args, &block) # :nodoc:
|
38
|
+
t = super
|
39
|
+
yield t if block_given?
|
40
|
+
t.define
|
41
|
+
end
|
42
|
+
|
43
|
+
# The full gem name like 'sprout-asunit3-library'
|
44
|
+
def gem_name
|
45
|
+
@gem_name ||= "sprout-#{name}-library"
|
46
|
+
end
|
47
|
+
|
48
|
+
# The path to the library source or swc that will be copied into your project.
|
49
|
+
# This can actually be any full or relative path on your system, but should almost
|
50
|
+
# always be left alone for automatic resolution.
|
51
|
+
def library_path
|
52
|
+
@library_path ||= nil
|
53
|
+
end
|
54
|
+
|
55
|
+
# Override the the project folder where the library will be installed.
|
56
|
+
#
|
57
|
+
# By default, libraries are installed into Sprout::ProjectModel +lib_dir+.
|
58
|
+
def project_lib
|
59
|
+
@project_lib ||= ProjectModel.instance.lib_dir
|
60
|
+
end
|
61
|
+
|
62
|
+
# Unlike other rake tasks, Library tasks are actually
|
63
|
+
# resolved at 'define' time. This allows the tool tasks
|
64
|
+
# to build their own dependencies (like file deps)
|
65
|
+
# (I'm sure there's a better way to do this, if you know how to fix this,
|
66
|
+
# and would like to contribute to sprouts, this might be a good spot for it)
|
67
|
+
def define
|
68
|
+
@file_target = sprout(gem_name, version)
|
69
|
+
@library_path = File.join(@file_target.installed_path, @file_target.archive_path)
|
70
|
+
define_file_task(library_path, project_path)
|
71
|
+
end
|
72
|
+
|
73
|
+
def execute(*args) # :nodoc:
|
74
|
+
super
|
75
|
+
end
|
76
|
+
|
77
|
+
# The path within the project where this library is installed
|
78
|
+
def project_path
|
79
|
+
if(File.directory?(@library_path))
|
80
|
+
# library is source dir
|
81
|
+
File.join(project_lib, name)
|
82
|
+
else
|
83
|
+
# library is a binary (like swc, jar, etc)
|
84
|
+
File.join(project_lib, File.basename(@file_target.archive_path))
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
private
|
89
|
+
|
90
|
+
def define_file_task(source, destination)
|
91
|
+
file destination do |t|
|
92
|
+
FileUtils.cp_r(library_path, destination)
|
93
|
+
end
|
94
|
+
prerequisites << destination
|
95
|
+
end
|
96
|
+
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
# Helper method for definining and accessing LibraryTask instances in a rakefile
|
101
|
+
def library(args, &block)
|
102
|
+
Sprout::LibraryTask.define_task(args, &block)
|
103
|
+
end
|
@@ -0,0 +1,245 @@
|
|
1
|
+
=begin
|
2
|
+
Copyright (c) 2007 Pattern Park
|
3
|
+
|
4
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
5
|
+
a copy of this software and associated documentation files (the
|
6
|
+
"Software"), to deal in the Software without restriction, including
|
7
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
8
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
9
|
+
permit persons to whom the Software is furnished to do so, subject to
|
10
|
+
the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be
|
13
|
+
included in all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
17
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
19
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
20
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
21
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
22
|
+
|
23
|
+
This class has been commented out because the termios feature
|
24
|
+
that allows users to more securely enter passwords does not
|
25
|
+
work in a DOS shell.
|
26
|
+
|
27
|
+
It would be greatly appreciate if someone refactored this to either:
|
28
|
+
a) Get the same functionality in a cross-platform manner
|
29
|
+
b) Only require and use termios on systems that allow it
|
30
|
+
=end
|
31
|
+
|
32
|
+
|
33
|
+
require 'net/ssh'
|
34
|
+
require 'net/sftp'
|
35
|
+
#require 'termios'
|
36
|
+
|
37
|
+
module Sprout
|
38
|
+
class SFTPError < StandardError #:nodoc:
|
39
|
+
end
|
40
|
+
|
41
|
+
# The SFTPTask provides a simple rake task interface to the SFTP client RubyGem.
|
42
|
+
# This task can allow you to easily push build artifacts to a remote server
|
43
|
+
# with a single shell command.
|
44
|
+
class SFTPTask < Rake::Task
|
45
|
+
|
46
|
+
# Collection of files that should be transmitted to the remote server
|
47
|
+
attr_accessor :files
|
48
|
+
# Host name of the server to connect to with no protocol prefix, like: sub.yourhost.com
|
49
|
+
attr_accessor :host
|
50
|
+
# Username to send to the remote host. You will be prompted for this value if it is left null.
|
51
|
+
#
|
52
|
+
# NOTE: You should never check a file into version control with this field filled in, it is
|
53
|
+
# provided here as a convenience for getting set up.
|
54
|
+
attr_accessor :username
|
55
|
+
# The mode for transmitted files. Defaults to 0644
|
56
|
+
attr_accessor :file_mode
|
57
|
+
# the mode for created directories. Defaults to 0755
|
58
|
+
attr_accessor :dir_mode
|
59
|
+
# The local path to mask from transmitted files. This is key feature for automated file transmission.
|
60
|
+
# For example, if you are sending a file:
|
61
|
+
# bin/assets/img/SomeImage.jpg
|
62
|
+
# into a directory on your server like:
|
63
|
+
# /var/www/someproject/
|
64
|
+
# You don't necessarily want the 'bin' folder copied over, so you set the local_path to 'bin' like:
|
65
|
+
# t.local_path = 'bin'
|
66
|
+
# and your server will have the file uploaded to:
|
67
|
+
# /var/www/someproject/assets/img/SomeImage.jpg
|
68
|
+
attr_accessor :local_path
|
69
|
+
# The Remote base path where files should be transmitted, can be absolute or relative.
|
70
|
+
attr_accessor :remote_path
|
71
|
+
# Password to send to the remote host. You will be prompted for this value if it is left null.
|
72
|
+
#
|
73
|
+
# NOTE: You should never check a file into version control with this field filled in, it is
|
74
|
+
# provided here as a convenience for getting set up.
|
75
|
+
attr_accessor :password
|
76
|
+
|
77
|
+
# TODO: Get this to automatically download and install requisite gems
|
78
|
+
def initialize(task_name, app)
|
79
|
+
super(task_name, app)
|
80
|
+
@name = name
|
81
|
+
@files = []
|
82
|
+
@host = ''
|
83
|
+
@dir_mode = 0755
|
84
|
+
@file_mode = 0644
|
85
|
+
end
|
86
|
+
|
87
|
+
def self.define_task(args, &block) # :nodoc:
|
88
|
+
t = super
|
89
|
+
yield t if block_given?
|
90
|
+
end
|
91
|
+
|
92
|
+
def execute(*args) # :nodoc:
|
93
|
+
if(@files.size == 0)
|
94
|
+
if(@local_path)
|
95
|
+
expr = @local_path + '/**/**/*'
|
96
|
+
@files = FileList[expr]
|
97
|
+
else
|
98
|
+
throw SFTPError.new('SFTP requires either a local_path or files to be transmitted')
|
99
|
+
end
|
100
|
+
else
|
101
|
+
if(!@local_path)
|
102
|
+
@local_path = ''
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
if(@host == '' || @host.nil?)
|
107
|
+
throw SFTPError.new('SFTP requires non-nil host parameter')
|
108
|
+
end
|
109
|
+
|
110
|
+
if(@username.nil?)
|
111
|
+
print "Username: "
|
112
|
+
@username = $stdin.gets.chomp!
|
113
|
+
throw SFTPError.new('SFTP requires username parameter') unless @username
|
114
|
+
end
|
115
|
+
|
116
|
+
if(@password.nil?)
|
117
|
+
@password = $stdin.gets.chomp!
|
118
|
+
# @password = Password.get
|
119
|
+
throw SFTPError.new('SFTP requires password parameter') unless @password
|
120
|
+
end
|
121
|
+
|
122
|
+
if(get_confirmation)
|
123
|
+
puts ">> Connecting to Remote Server: #{@username}@#{@host}:#{@remote_path}"
|
124
|
+
|
125
|
+
Net::SFTP.start(@host, @username, @password) do |sftp|
|
126
|
+
begin
|
127
|
+
dir = sftp.opendir(@remote_path)
|
128
|
+
rescue Net::SFTP::Operations::StatusException
|
129
|
+
puts "[ERROR] [#{@remote_path}] does not exist on the server"
|
130
|
+
return
|
131
|
+
end
|
132
|
+
for file in @files
|
133
|
+
next if File.stat(file).directory?
|
134
|
+
remote_file = remote_file_name(file)
|
135
|
+
put_file(file, remote_file, sftp)
|
136
|
+
end
|
137
|
+
end
|
138
|
+
else
|
139
|
+
puts "[WARNING] Publish aborted by user request"
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
def put_file(local_file, remote_file, sftp) # :nodoc:
|
144
|
+
begin
|
145
|
+
create_remote_dir(remote_file, sftp)
|
146
|
+
|
147
|
+
if(file_changed(local_file, remote_file, sftp))
|
148
|
+
puts ">> Pushing #{local_file} to: #{remote_file}"
|
149
|
+
sftp.put_file(local_file, remote_file)
|
150
|
+
end
|
151
|
+
rescue Net::SFTP::Operations::StatusException => e
|
152
|
+
raise unless e.code == 2
|
153
|
+
sftp.put_file(local_file, remote_file)
|
154
|
+
sftp.setstat(remote_file, :permissions => @file_mode)
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
def create_remote_dir(path, sftp) # :nodoc:
|
159
|
+
begin
|
160
|
+
sftp.stat(File.dirname(path))
|
161
|
+
rescue Net::SFTP::Operations::StatusException => e
|
162
|
+
raise unless e.code == 2
|
163
|
+
dir = File.dirname(path.sub(@remote_path, ''))
|
164
|
+
parts = dir.split(File::SEPARATOR)
|
165
|
+
part = File.join(@remote_path, parts.shift)
|
166
|
+
while(part)
|
167
|
+
begin
|
168
|
+
sftp.stat(part)
|
169
|
+
rescue Net::SFTP::Operations::StatusException => e
|
170
|
+
raise unless e.code == 2
|
171
|
+
sftp.mkdir(part, :permissions => @dir_mode)
|
172
|
+
end
|
173
|
+
if(parts.size > 0)
|
174
|
+
part = File.join(part, parts.shift)
|
175
|
+
else
|
176
|
+
part = nil
|
177
|
+
end
|
178
|
+
end
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
def file_changed(local_file, remote_file, sftp) # :nodoc:
|
183
|
+
local_stat = File.stat(local_file)
|
184
|
+
remote_stat = sftp.stat(remote_file)
|
185
|
+
time_difference = (local_stat.mtime > Time.at(remote_stat.mtime))
|
186
|
+
size_difference = (local_stat.size != remote_stat.size)
|
187
|
+
return (time_difference || size_difference)
|
188
|
+
end
|
189
|
+
|
190
|
+
def remote_file_name(file) # :nodoc:
|
191
|
+
return @remote_path + file.sub(@local_path, '')
|
192
|
+
end
|
193
|
+
|
194
|
+
def get_confirmation # :nodoc:
|
195
|
+
puts "-----------------------------------------"
|
196
|
+
puts "Are you sure you want to publish #{@files.size} files to:"
|
197
|
+
puts "#{@username}@#{@host}:#{@remote_path}? [Yn]"
|
198
|
+
response = $stdin.gets.chomp!
|
199
|
+
return (response.downcase == 'y' || response == "")
|
200
|
+
end
|
201
|
+
|
202
|
+
end
|
203
|
+
|
204
|
+
=begin
|
205
|
+
# The following implementation does not work at all on DOS machines,
|
206
|
+
# is there a cross-platform way to solve the secure password prompt problem?
|
207
|
+
# Password handling snippet found at: http://www.caliban.org/ruby/ruby-password.shtml
|
208
|
+
class Password
|
209
|
+
|
210
|
+
def Password.get(message="Password: ")
|
211
|
+
begin
|
212
|
+
if $stdin.tty?
|
213
|
+
Password.echo false
|
214
|
+
print message if message
|
215
|
+
end
|
216
|
+
|
217
|
+
return $stdin.gets.chomp
|
218
|
+
ensure
|
219
|
+
if $stdin.tty?
|
220
|
+
Password.echo true
|
221
|
+
print "\n"
|
222
|
+
end
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
226
|
+
def Password.echo(on=true, masked=false)
|
227
|
+
term = Termios::getattr( $stdin )
|
228
|
+
|
229
|
+
if on
|
230
|
+
term.c_lflag |= ( Termios::ECHO | Termios::ICANON )
|
231
|
+
else # off
|
232
|
+
term.c_lflag &= ~Termios::ECHO
|
233
|
+
term.c_lflag &= ~Termios::ICANON if masked
|
234
|
+
end
|
235
|
+
|
236
|
+
Termios::setattr( $stdin, Termios::TCSANOW, term )
|
237
|
+
end
|
238
|
+
end
|
239
|
+
=end
|
240
|
+
end
|
241
|
+
|
242
|
+
|
243
|
+
def sftp(args, &block)
|
244
|
+
Sprout::SFTPTask.define_task(args, &block)
|
245
|
+
end
|