sprout 0.7.219-i686-darwin10

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,134 @@
1
+ require 'sprout/version_file'
2
+
3
+ module Sprout
4
+
5
+ class GitTaskError < StandardError; end
6
+
7
+ # A Rake task for continous integration and automated deployment.
8
+ # This task will automatically load a +version_file+, increment
9
+ # the last digit (revision), create a new tag in Git with the full
10
+ # version number, and push tags to the remote Git repository.
11
+ #
12
+ # To use this task, simply add the following to your rakefile:
13
+ #
14
+ # desc 'Increment revision, tag and push with git'
15
+ # git :tag do |t|
16
+ # t.version_file = 'version.txt'
17
+ # end
18
+ #
19
+
20
+ class GitTask < Rake::Task
21
+ # Path to a plain text file that contains a three-part version number.
22
+ # @see VersionFile
23
+ attr_accessor :version_file
24
+ # The remote branch to use, defaults to 'origin'.
25
+ attr_accessor :remote
26
+ # The local branch to send, defaults to 'master'.
27
+ attr_accessor :branch
28
+ # Message to use when committing after incrementing revision number.
29
+ # Defaults to 'Incremented revision number'.
30
+ attr_accessor :commit_message
31
+
32
+ def initialize(name, app)
33
+ super
34
+ @remote = 'origin'
35
+ @branch = 'master'
36
+ @commit_message = 'Incremented revision number'
37
+ end
38
+
39
+ def version
40
+ @version.to_s
41
+ end
42
+
43
+ def define
44
+ validate
45
+ @version = VersionFile.new(version_file)
46
+ end
47
+
48
+ def execute(*args)
49
+ super
50
+ # Fix numeric comparison....
51
+ while(get_tags.index(@version.to_tag)) do
52
+ @version.increment_revision
53
+ end
54
+ create_tag(@version.to_tag)
55
+ commit
56
+ push
57
+ end
58
+
59
+ def self.define_task(args, &block)
60
+ begin
61
+ require 'git'
62
+ rescue LoadError => e
63
+ puts "You need to install the 'git' gem. Try running: sudo gem install git"
64
+ raise e
65
+ end
66
+ t = super
67
+ yield t if block_given?
68
+ t.define
69
+ return t
70
+ end
71
+
72
+ # Accessor for mocking the git gem.
73
+ def scm=(scm)
74
+ @scm = scm
75
+ end
76
+
77
+ # Will open on path if no SCM exists yet.
78
+ def scm
79
+ if(@scm.nil?)
80
+ path = path_to_git
81
+ raise GitTaskError.new("We don't appear to be inside of a git repository") if path.nil?
82
+ @scm = Git.open(path)
83
+ end
84
+
85
+ @scm
86
+ end
87
+
88
+ private
89
+
90
+ def push
91
+ `git push #{remote} #{branch} --tags`
92
+ end
93
+
94
+ def commit
95
+ `git commit -a -m "#{commit_message}"`
96
+ end
97
+
98
+ def path_to_git
99
+ git = '.git'
100
+ parts = Dir.pwd.split(File::SEPARATOR)
101
+
102
+ while(parts.size > 0) do
103
+ path = parts.join(File::SEPARATOR)
104
+ if(File.exists?(File.join(path, git)))
105
+ return path
106
+ end
107
+ parts.pop
108
+ end
109
+
110
+ return nil
111
+ end
112
+
113
+ def get_tags
114
+ return scm.tags.collect do |t|
115
+ t.name
116
+ end
117
+ end
118
+
119
+ def create_tag(name)
120
+ scm.add_tag name
121
+ end
122
+
123
+ def validate
124
+ raise GitTaskError.new("task.version_file is a required configuration for GitTask") if version_file.nil?
125
+ end
126
+
127
+ end
128
+
129
+ end
130
+
131
+ # Helper method for definining the git task in a rakefile
132
+ def git(args, &block)
133
+ Sprout::GitTask.define_task(args, &block)
134
+ end
@@ -0,0 +1,118 @@
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-#{clean_name}-library"
46
+ end
47
+
48
+ # Ensure that namespaced rake tasks only use
49
+ # the final part for name-based features
50
+ def clean_name
51
+ return name.split(':').pop
52
+ end
53
+
54
+ # The path to the library source or swc that will be copied into your project.
55
+ # This can actually be any full or relative path on your system, but should almost
56
+ # always be left alone for automatic resolution.
57
+ def library_path
58
+ @library_path ||= nil
59
+ end
60
+
61
+ # Override the the project folder where the library will be installed.
62
+ #
63
+ # By default, libraries are installed into Sprout::ProjectModel +lib_dir+.
64
+ def project_lib
65
+ if(library_path.index('.swc'))
66
+ @project_lib ||= ProjectModel.instance.swc_dir
67
+ else
68
+ @project_lib ||= ProjectModel.instance.lib_dir
69
+ end
70
+ end
71
+
72
+ # Unlike other rake tasks, Library tasks are actually
73
+ # resolved at 'define' time. This allows the tool tasks
74
+ # to build their own dependencies (like file deps)
75
+ # (I'm sure there's a better way to do this, if you know how to fix this,
76
+ # and would like to contribute to sprouts, this might be a good spot for it)
77
+ def define
78
+ @file_target = sprout(gem_name, version)
79
+ @library_path = File.join(@file_target.installed_path, @file_target.archive_path)
80
+ define_file_task(library_path, project_path)
81
+ end
82
+
83
+ def execute(*args) # :nodoc:
84
+ super
85
+ end
86
+
87
+ # The path within the project where this library is installed
88
+ def project_path
89
+ if(File.directory?(@library_path))
90
+ # library is source dir
91
+ File.join(project_lib, clean_name)
92
+ else
93
+ # library is a binary (like swc, jar, etc)
94
+ File.join(project_lib, File.basename(@file_target.archive_path))
95
+ end
96
+ end
97
+
98
+ private
99
+
100
+ def define_file_task(source, destination)
101
+ file destination do |t|
102
+ lib_path = library_path
103
+ FileUtils.makedirs(destination)
104
+ if(File.directory?(lib_path))
105
+ lib_path = "#{lib_path}/."
106
+ end
107
+ FileUtils.cp_r(lib_path, destination)
108
+ end
109
+ prerequisites << destination
110
+ end
111
+
112
+ end
113
+ end
114
+
115
+ # Helper method for definining and accessing LibraryTask instances in a rakefile
116
+ def library(args, &block)
117
+ Sprout::LibraryTask.define_task(args, &block)
118
+ end
@@ -0,0 +1,248 @@
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
+ #gem 'net-ssh', '1.1.4'
33
+ #gem 'net-sftp', '1.1.1'
34
+
35
+ require 'net/ssh'
36
+ require 'net/sftp'
37
+
38
+ #require 'termios'
39
+
40
+ module Sprout
41
+ class SFTPError < StandardError #:nodoc:
42
+ end
43
+
44
+ # The SFTPTask provides a simple rake task interface to the SFTP client RubyGem.
45
+ # This task can allow you to easily push build artifacts to a remote server
46
+ # with a single shell command.
47
+ class SFTPTask < Rake::Task
48
+
49
+ # Collection of files that should be transmitted to the remote server
50
+ attr_accessor :files
51
+ # Host name of the server to connect to with no protocol prefix, like: sub.yourhost.com
52
+ attr_accessor :host
53
+ # Username to send to the remote host. You will be prompted for this value if it is left null.
54
+ #
55
+ # NOTE: You should never check a file into version control with this field filled in, it is
56
+ # provided here as a convenience for getting set up.
57
+ attr_accessor :username
58
+ # The mode for transmitted files. Defaults to 0644
59
+ attr_accessor :file_mode
60
+ # the mode for created directories. Defaults to 0755
61
+ attr_accessor :dir_mode
62
+ # The local path to mask from transmitted files. This is key feature for automated file transmission.
63
+ # For example, if you are sending a file:
64
+ # bin/assets/img/SomeImage.jpg
65
+ # into a directory on your server like:
66
+ # /var/www/someproject/
67
+ # You don't necessarily want the 'bin' folder copied over, so you set the local_path to 'bin' like:
68
+ # t.local_path = 'bin'
69
+ # and your server will have the file uploaded to:
70
+ # /var/www/someproject/assets/img/SomeImage.jpg
71
+ attr_accessor :local_path
72
+ # The Remote base path where files should be transmitted, can be absolute or relative.
73
+ attr_accessor :remote_path
74
+ # Password to send to the remote host. You will be prompted for this value if it is left null.
75
+ #
76
+ # NOTE: You should never check a file into version control with this field filled in, it is
77
+ # provided here as a convenience for getting set up.
78
+ attr_accessor :password
79
+
80
+ def initialize(task_name, app)
81
+ super(task_name, app)
82
+ @name = name
83
+ @files = []
84
+ @dir_mode = 0755
85
+ @file_mode = 0644
86
+ @host = nil
87
+ end
88
+
89
+ def self.define_task(args, &block) # :nodoc:
90
+ t = super
91
+ yield t if block_given?
92
+ end
93
+
94
+ def execute(*args) # :nodoc:
95
+ if(@files.size == 0)
96
+ if(@local_path)
97
+ expr = @local_path + '/**/**/*'
98
+ @files = FileList[expr]
99
+ else
100
+ raise SFTPError.new('SFTP requires either a local_path or files to be transmitted')
101
+ end
102
+ else
103
+ if(!@local_path)
104
+ @local_path = ''
105
+ end
106
+ end
107
+
108
+ if(@host.nil?)
109
+ raise SFTPError.new('SFTP requires non-nil host parameter')
110
+ end
111
+
112
+ if(@username.nil?)
113
+ print "Username: "
114
+ @username = $stdin.gets.chomp!
115
+ raise SFTPError.new('SFTP requires username parameter') unless @username
116
+ end
117
+
118
+ if(@password.nil?)
119
+ print "Password: "
120
+ @password = $stdin.gets.chomp!
121
+ # @password = Password.get
122
+ raise SFTPError.new('SFTP requires password parameter') unless @password
123
+ end
124
+
125
+ if(get_confirmation)
126
+ puts ">> Connecting to Remote Server: #{@username}@#{@host}:#{@remote_path}"
127
+
128
+ Net::SFTP.start(@host, @username, @password) do |sftp|
129
+ begin
130
+ dir = sftp.opendir(@remote_path)
131
+ rescue Net::SFTP::Operations::StatusException
132
+ puts "[ERROR] [#{@remote_path}] does not exist on the server"
133
+ return
134
+ end
135
+ for file in @files
136
+ next if File.stat(file).directory?
137
+ remote_file = remote_file_name(file)
138
+ put_file(file, remote_file, sftp)
139
+ end
140
+ end
141
+ else
142
+ puts "[WARNING] Publish aborted by user request"
143
+ end
144
+ end
145
+
146
+ def put_file(local_file, remote_file, sftp) # :nodoc:
147
+ begin
148
+ create_remote_dir(remote_file, sftp)
149
+
150
+ if(file_changed(local_file, remote_file, sftp))
151
+ puts ">> Pushing #{local_file} to: #{remote_file}"
152
+ sftp.put_file(local_file, remote_file)
153
+ end
154
+ rescue Net::SFTP::Operations::StatusException => e
155
+ raise unless e.code == 2
156
+ sftp.put_file(local_file, remote_file)
157
+ sftp.setstat(remote_file, :permissions => @file_mode)
158
+ end
159
+ end
160
+
161
+ def create_remote_dir(path, sftp) # :nodoc:
162
+ begin
163
+ sftp.stat(File.dirname(path))
164
+ rescue Net::SFTP::Operations::StatusException => e
165
+ raise unless e.code == 2
166
+ dir = File.dirname(path.sub(@remote_path, ''))
167
+ parts = dir.split(File::SEPARATOR)
168
+ part = File.join(@remote_path, parts.shift)
169
+ while(part)
170
+ begin
171
+ sftp.stat(part)
172
+ rescue Net::SFTP::Operations::StatusException => ne
173
+ raise unless ne.code == 2
174
+ sftp.mkdir(part, :permissions => @dir_mode)
175
+ end
176
+ if(parts.size > 0)
177
+ part = File.join(part, parts.shift)
178
+ else
179
+ part = nil
180
+ end
181
+ end
182
+ end
183
+ end
184
+
185
+ def file_changed(local_file, remote_file, sftp) # :nodoc:
186
+ local_stat = File.stat(local_file)
187
+ remote_stat = sftp.stat(remote_file)
188
+ time_difference = (local_stat.mtime > Time.at(remote_stat.mtime))
189
+ size_difference = (local_stat.size != remote_stat.size)
190
+ return (time_difference || size_difference)
191
+ end
192
+
193
+ def remote_file_name(file) # :nodoc:
194
+ return @remote_path + file.sub(@local_path, '')
195
+ end
196
+
197
+ def get_confirmation # :nodoc:
198
+ puts "-----------------------------------------"
199
+ puts "Are you sure you want to publish #{@files.size} files to:"
200
+ puts "#{@username}@#{@host}:#{@remote_path}? [Yn]"
201
+ response = $stdin.gets.chomp!
202
+ return (response.downcase == 'y' || response == "")
203
+ end
204
+
205
+ end
206
+
207
+ =begin
208
+ # The following implementation does not work at all on DOS machines,
209
+ # is there a cross-platform way to solve the secure password prompt problem?
210
+ # Password handling snippet found at: http://www.caliban.org/ruby/ruby-password.shtml
211
+ class Password
212
+
213
+ def Password.get(message="Password: ")
214
+ begin
215
+ if $stdin.tty?
216
+ Password.echo false
217
+ print message if message
218
+ end
219
+
220
+ return $stdin.gets.chomp
221
+ ensure
222
+ if $stdin.tty?
223
+ Password.echo true
224
+ print "\n"
225
+ end
226
+ end
227
+ end
228
+
229
+ def Password.echo(on=true, masked=false)
230
+ term = Termios::getattr( $stdin )
231
+
232
+ if on
233
+ term.c_lflag |= ( Termios::ECHO | Termios::ICANON )
234
+ else # off
235
+ term.c_lflag &= ~Termios::ECHO
236
+ term.c_lflag &= ~Termios::ICANON if masked
237
+ end
238
+
239
+ Termios::setattr( $stdin, Termios::TCSANOW, term )
240
+ end
241
+ end
242
+ =end
243
+ end
244
+
245
+
246
+ def sftp(args, &block)
247
+ Sprout::SFTPTask.define_task(args, &block)
248
+ end