frank 1.0.9 → 1.0.10

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,3 +1,13 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ frank (1.0.9)
5
+ haml (~> 3.0)
6
+ mongrel (~> 1.2.0.pre2)
7
+ net-ssh (~> 2.0)
8
+ rack (~> 1.1)
9
+ tilt (~> 1.3)
10
+
1
11
  GEM
2
12
  remote: http://rubygems.org/
3
13
  specs:
@@ -10,7 +20,6 @@ GEM
10
20
  coffee-script-source (1.1.2)
11
21
  compass (0.10.2)
12
22
  haml (>= 3.0.4)
13
- contest (0.1.2)
14
23
  daemons (1.0.10)
15
24
  diff-lcs (1.1.2)
16
25
  erubis (2.6.6)
@@ -18,26 +27,24 @@ GEM
18
27
  execjs (1.2.4)
19
28
  multi_json (~> 1.0)
20
29
  gem_plugin (0.2.3)
21
- gemcutter (0.6.1)
22
- git (1.2.5)
23
30
  haml (3.0.13)
24
- jeweler (1.4.0)
25
- gemcutter (>= 0.1.0)
26
- git (>= 1.2.5)
27
- rubyforge (>= 2.0.0)
28
- json_pure (1.4.3)
29
31
  less (1.2.21)
30
32
  mutter (>= 0.4.2)
31
33
  treetop (>= 1.4.2)
32
34
  liquid (2.1.2)
35
+ metaclass (0.0.1)
36
+ mocha (0.10.5)
37
+ metaclass (~> 0.0.1)
33
38
  mongrel (1.2.0.pre2)
34
39
  daemons (~> 1.0.10)
35
40
  gem_plugin (~> 0.2.3)
36
41
  multi_json (1.0.3)
37
42
  mutter (0.5.3)
38
- net-scp (1.0.1)
43
+ net-scp (1.0.4)
39
44
  net-ssh (>= 1.99.1)
40
- net-ssh (2.0.23)
45
+ net-sftp (2.0.5)
46
+ net-ssh (>= 2.0.9)
47
+ net-ssh (2.3.0)
41
48
  polyglot (0.3.1)
42
49
  rack (1.2.1)
43
50
  rack-test (0.5.4)
@@ -52,8 +59,6 @@ GEM
52
59
  rspec-expectations (2.6.0)
53
60
  diff-lcs (~> 1.1.2)
54
61
  rspec-mocks (2.6.0)
55
- rubyforge (2.0.4)
56
- json_pure (>= 1.1.7)
57
62
  tilt (1.3.3)
58
63
  treetop (1.4.8)
59
64
  polyglot (>= 0.3.1)
@@ -66,18 +71,14 @@ DEPENDENCIES
66
71
  builder
67
72
  coffee-script (~> 2.2.0)
68
73
  compass (~> 0.10.2)
69
- contest
70
74
  erubis
71
- haml (~> 3.0)
72
- jeweler
75
+ frank!
73
76
  less
74
77
  liquid
75
- mongrel (~> 1.2.0.pre2)
76
- net-scp (~> 1.0)
77
- net-ssh (~> 2.0)
78
- rack (~> 1.1)
78
+ mocha
79
+ net-scp
80
+ net-sftp
79
81
  rack-test (~> 0.5)
80
82
  rake
81
83
  rdiscount
82
84
  rspec (~> 2.6.0)
83
- tilt (~> 1.3)
data/Rakefile CHANGED
@@ -1 +1,8 @@
1
1
  require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+
4
+ desc "Run all specs"
5
+ RSpec::Core::RakeTask.new do |t|
6
+ t.name = :tests
7
+ t.pattern = "spec/**/*_spec.rb"
8
+ end
@@ -16,18 +16,18 @@ Gem::Specification.new do |s|
16
16
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
17
17
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
18
18
  s.require_paths = ["lib"]
19
-
19
+
20
20
  s.add_runtime_dependency 'rack', '~> 1.1'
21
21
  s.add_runtime_dependency 'mongrel', '~> 1.2.0.pre2'
22
22
  s.add_runtime_dependency 'haml', '~> 3.0'
23
23
  s.add_runtime_dependency 'tilt', '~> 1.3'
24
24
  s.add_runtime_dependency 'net-ssh', '~> 2.0'
25
- s.add_runtime_dependency 'net-scp', '~> 1.0'
26
-
25
+
27
26
  s.add_development_dependency 'rspec', '~> 2.6.0'
28
27
  s.add_development_dependency 'rack-test', '~> 0.5'
29
28
  s.add_development_dependency 'rake'
30
29
  s.add_development_dependency 'builder'
30
+ s.add_development_dependency 'mocha'
31
31
  s.add_development_dependency 'erubis'
32
32
  s.add_development_dependency 'compass', '~> 0.10.2'
33
33
  s.add_development_dependency 'rdiscount'
@@ -35,4 +35,6 @@ Gem::Specification.new do |s|
35
35
  s.add_development_dependency 'less'
36
36
  s.add_development_dependency 'coffee-script', '~> 2.2.0'
37
37
  s.add_development_dependency 'RedCloth'
38
- end
38
+ s.add_development_dependency 'net-scp'
39
+ s.add_development_dependency 'net-sftp'
40
+ end
@@ -223,15 +223,6 @@ module Frank
223
223
  Frank.reset
224
224
  Frank.root = new_root if new_root
225
225
 
226
- if %w[publish p].include? ARGV.first
227
- begin
228
- require 'net/ssh'
229
- require 'net/scp'
230
- rescue LoadError
231
- puts "\033[31mpublish requires the 'net-scp' gem. `gem install net-scp'\033[0m"
232
- exit!
233
- end
234
- end
235
226
 
236
227
  # setup compass
237
228
  begin
@@ -130,7 +130,7 @@ module Frank
130
130
  when 'publish', 'p'
131
131
  # compile the project and scp it to server
132
132
  Frank.publishing!
133
- Frank::Publish::SCP.execute!
133
+ Frank::Publish.execute!
134
134
  when 'upgrade'
135
135
  # upgrade if we need to upgrade
136
136
  Frank.upgrade!
@@ -1,7 +1,7 @@
1
1
  module Frank
2
2
  module Middleware
3
3
  class Statik
4
-
4
+
5
5
  def initialize(app, options={})
6
6
  @app = app
7
7
  frank_root = File.expand_path(File.dirname(File.dirname(__FILE__))) + '/templates'
@@ -9,13 +9,13 @@ module Frank
9
9
  @frank_server = Rack::File.new(frank_root)
10
10
  @static_server = Rack::File.new(root)
11
11
  end
12
-
12
+
13
13
  # handles serving from __frank__
14
14
  # looks for static access, if not found,
15
15
  # passes request to frank
16
16
  def call(env)
17
17
  path = env['PATH_INFO'].dup
18
-
18
+
19
19
  if path.include? '__frank__'
20
20
  env['PATH_INFO'].gsub!('/__frank__', '')
21
21
  result = @frank_server.call(env)
@@ -24,18 +24,18 @@ module Frank
24
24
  env['PATH_INFO'] << 'index.html' if path[-1..-1] == '/'
25
25
  result = @static_server.call(env)
26
26
  end
27
-
27
+
28
28
  # return if static assets found
29
29
  # else reset the path and pass to frank
30
- if result[0] == 200
30
+ if result[0] == 200 || result[0] == 304
31
31
  result
32
32
  else
33
33
  env['PATH_INFO'] = path
34
34
  @app.call(env)
35
35
  end
36
-
36
+
37
37
  end
38
-
38
+
39
39
  end
40
40
  end
41
- end
41
+ end
@@ -1,68 +1,76 @@
1
1
  module Frank
2
2
  module Publish
3
3
 
4
- class SCP
5
- def self.execute!
6
- exit_unless_configured
7
4
 
8
- unless Frank.silent_export?
9
- puts "\nFrank is..."
10
- puts " - \033[32mExporting templates\033[0m"
11
- end
5
+ def self.execute!
6
+ protocol = exit_unless_configured.to_s
12
7
 
13
- tmp_folder = "/tmp/frankexp-#{Frank.proj_name}"
8
+ ok_message "", "\nFrank is..."
9
+ ok_message "Exporting templates", " - "
14
10
 
15
- # remove stale folder if it exists
16
- FileUtils.rm_rf(tmp_folder) if File.exist?(tmp_folder)
11
+ # upload the files and report progress
12
+ ok_message "Publishing to: `#{Frank.publish.host}:#{Frank.publish.path}' via #{protocol}", " - "
17
13
 
18
- # dump the project in production mode to tmp folder
19
- Frank.export.path = tmp_folder
20
- Frank.export.silent = true
21
- Frank::Compile.export!
22
14
 
23
- puts " - \033[32mPublishing to:\033[0m `#{Frank.publish.host}:#{Frank.publish.path}'" unless Frank.silent_export?
15
+ req = "frank/publish/#{protocol.downcase}"
16
+ rescue_load_error protocol do
17
+ require req
18
+ clazz = Frank::Publish.const_get(protocol.upcase)
19
+ publisher = clazz.new(Frank.publish)
20
+ publisher.perform!
21
+ end
24
22
 
25
- ssh_options = {
26
- :password => Frank.publish.password,
27
- :port => Frank.publish.port
28
- }
23
+ ok_message "\nPublish complete!"
24
+ end
29
25
 
30
- current = nil
26
+ def self.exit_unless_configured
27
+ required_settings = {:host => Frank.publish.host, :path => Frank.publish.path, :username => Frank.publish.username}
31
28
 
32
- # upload the files and report progress
33
- Net::SSH.start(Frank.publish.host, Frank.publish.username, ssh_options) do |ssh|
34
- ssh.scp.upload!("#{tmp_folder}/", Frank.publish.path, :recursive => true, :chunk_size => 2048) do |ch, name, sent, total|
29
+ should_exit = false
30
+ message = ""
35
31
 
36
- puts " - #{name[tmp_folder.length..-1]}" unless name == current || Frank.silent_export?
32
+ protocol = Frank.publish.mode || :scp
33
+ unless [:ftp, :ftptls, :sftp, :scp].include?(protocol.to_sym)
34
+ message << "Frank.publish.mode = #{protocol} is not supported. Supported publish modes are 'ftp', 'ftptls', 'sftp' or 'scp' (default)\n"
35
+ should_exit = true
36
+ end
37
37
 
38
- current = name
39
- end
38
+ required_settings.each do |name, value|
39
+ if value.nil?
40
+ message << "Frank.publish.#{name} is required to publish. You can configure it in setup.rb\n"
41
+ should_exit = true
40
42
  end
43
+ end
41
44
 
42
- # cleanup by removing tmp folder
43
- FileUtils.rm_rf(tmp_folder)
44
45
 
45
- puts "\n\033[32mPublish complete!\033[0m" unless Frank.silent_export?
46
+ if should_exit
47
+ err_message message
48
+ exit!
46
49
  end
47
50
 
48
- def self.exit_unless_configured
49
- required_settings = { :host => Frank.publish.host, :path => Frank.publish.path, :username => Frank.publish.username }
50
- should_exit = false
51
- message = "\033[31m"
51
+ protocol
52
+ end
52
53
 
53
- required_settings.each do |name, value|
54
- if value.nil?
55
- message << "Frank.publish.#{name} is required to publish. You can configure it in setup.rb\n"
56
- exiting = true
57
- end
58
- end
54
+ def self.rescue_load_error protocol, &blk
55
+ gem = "net-#{protocol}"
56
+ begin
57
+ yield
58
+ rescue LoadError
59
+ err_message "Publishing via #{protocol} requires the '#{gem}' gem. `gem install #{gem}'"
60
+ exit!
61
+ end
62
+ end
59
63
 
60
- message << "\033[0m"
61
64
 
62
- puts message and exit! if should_exit
63
- end
65
+ def self.ok_message str, prefix = ''
66
+ puts "#{prefix}\033[32m#{str}\033[0m"
67
+ end
64
68
 
69
+ def self.err_message str, prefix = ''
70
+ puts "#{prefix}\033[31m#{str}\033[0m"
65
71
  end
66
72
 
73
+
67
74
  end
75
+
68
76
  end
@@ -0,0 +1,94 @@
1
+ module Frank
2
+ module Publish
3
+ class Base
4
+
5
+ attr_accessor :username, :password
6
+ attr_accessor :hostname, :port
7
+ attr_accessor :remote_path
8
+ attr_accessor :local_path
9
+
10
+
11
+ def initialize(options)
12
+ @username = options.user || options.username
13
+ @password = options.password
14
+ @hostname = options.host
15
+ @remote_path = options.path
16
+ @port = options.port
17
+ @local_path = "/tmp/frank-publish-#{Frank.proj_name}-#{Time.now.to_i}"
18
+ end
19
+
20
+ ##
21
+ # Performs the backup transfer
22
+ def perform!
23
+ export!
24
+ begin
25
+ transfer!
26
+ rescue SocketError
27
+ err_message "Transfer failed. SocketError. Do you have internet?"
28
+ end
29
+ cleanup!
30
+ end
31
+
32
+
33
+ private
34
+
35
+ def export!
36
+ # remove stale folder if it exists
37
+ FileUtils.rm_rf(local_path) if File.exist?(local_path)
38
+
39
+ # dump the project in production mode to tmp folder
40
+ Frank.export.path = @local_path
41
+ Frank.export.silent = true
42
+ Frank::Compile.export!
43
+ end
44
+
45
+
46
+ ##
47
+ # returns a local_path relative list of all files to transfer for this export
48
+ def files_to_transfer
49
+ list = []
50
+ return list unless File.exist?(local_path)
51
+
52
+ Dir.chdir(local_path) do
53
+ list = Dir.glob("**/*").map do |f|
54
+ f unless File.directory? f
55
+ end.compact!
56
+ end
57
+
58
+ list
59
+ end
60
+
61
+ ##
62
+ # returns a local_path relative list of all directories to export
63
+ def directories
64
+ list = []
65
+ return list unless File.exist?(local_path)
66
+
67
+ Dir.chdir(local_path) do
68
+ list = Dir.glob("**/*").map do |f|
69
+ f if File.directory? f
70
+ end.compact!
71
+ end
72
+
73
+ list
74
+ end
75
+
76
+ def cleanup!
77
+ FileUtils.rm_rf(@local_path)
78
+ end
79
+
80
+ # ZOMG, we a need a Logger or sth.
81
+ def ok_message *args
82
+ Frank::Publish.ok_message *args
83
+ end
84
+
85
+ def err_message *args
86
+ Frank::Publish.err_message *args
87
+ end
88
+
89
+
90
+ end
91
+
92
+
93
+ end
94
+ end
@@ -0,0 +1,80 @@
1
+ require 'frank/publish/base'
2
+ require 'net/ftp'
3
+
4
+ module Frank
5
+ module Publish
6
+
7
+ class FTP < Base
8
+
9
+ def initialize(options, &block)
10
+ super(options)
11
+ instance_eval(&block) if block_given?
12
+
13
+ @port ||= 21
14
+ @remote_path = remote_path.sub(/^\~\//, '').sub(/^\//, '')
15
+ end
16
+
17
+ private
18
+
19
+ ##
20
+ # Establishes a connection to the remote server
21
+ #
22
+ # Note:
23
+ # Since the FTP port is defined as a constant in the Net::FTP class, and
24
+ # might be required to change by the user, we dynamically remove and
25
+ # re-add the constant with the provided port value
26
+ def connection
27
+ if Net::FTP.const_defined?(:FTP_PORT)
28
+ Net::FTP.send(:remove_const, :FTP_PORT)
29
+ end; Net::FTP.send(:const_set, :FTP_PORT, port)
30
+
31
+ Net::FTP.open(hostname, username, password) do |ftp|
32
+ ftp.passive = true
33
+ yield ftp
34
+ end
35
+ end
36
+
37
+ ##
38
+ # Transfers the archived file to the specified remote server
39
+ def transfer!
40
+ connection do |ftp|
41
+ directories.each do |dir|
42
+ create_remote_path(File.join(remote_path, dir), ftp)
43
+ end
44
+
45
+ files_to_transfer.each do |file|
46
+ ok_message "Uploading #{file}", " - "
47
+ ftp.put(
48
+ File.join(local_path, file),
49
+ File.join(remote_path, file)
50
+ )
51
+ end
52
+ end
53
+ end
54
+
55
+ ##
56
+ # Creates (if they don't exist yet) all the directories on the remote
57
+ # server in order to upload the backup file. Net::FTP does not support
58
+ # paths to directories that don't yet exist when creating new
59
+ # directories. Instead, we split the parts up in to an array (for each
60
+ # '/') and loop through that to create the directories one by one.
61
+ # Net::FTP raises an exception when the directory it's trying to create
62
+ # already exists, so we have rescue it
63
+ def create_remote_path(remote_path, ftp)
64
+ path_parts = []
65
+ remote_path.split('/').each do |path_part|
66
+ path_parts << path_part
67
+ begin
68
+ dir = path_parts.join('/')
69
+ ftp.mkdir(dir) unless dir.empty?
70
+ rescue Net::FTPPermError;
71
+ end
72
+ end
73
+ end
74
+
75
+
76
+ end
77
+
78
+
79
+ end
80
+ end