frank 1.0.9 → 1.0.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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