adva-static 0.0.1
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.
- data/lib/adva/static/export/page.rb +45 -0
- data/lib/adva/static/export/path.rb +49 -0
- data/lib/adva/static/export/queue.rb +27 -0
- data/lib/adva/static/export/store.rb +30 -0
- data/lib/adva/static/export/templates/config.ru +14 -0
- data/lib/adva/static/export.rb +104 -0
- data/lib/adva/static/import/format.rb +58 -0
- data/lib/adva/static/import/model/base.rb +78 -0
- data/lib/adva/static/import/model/blog.rb +33 -0
- data/lib/adva/static/import/model/page.rb +33 -0
- data/lib/adva/static/import/model/post.rb +78 -0
- data/lib/adva/static/import/model/section.rb +51 -0
- data/lib/adva/static/import/model/site.rb +59 -0
- data/lib/adva/static/import/model.rb +21 -0
- data/lib/adva/static/import/request.rb +92 -0
- data/lib/adva/static/import/source.rb +82 -0
- data/lib/adva/static/import.rb +42 -0
- data/lib/adva/static/rack/export.rb +59 -0
- data/lib/adva/static/rack/request.rb +39 -0
- data/lib/adva/static/rack/static.rb +40 -0
- data/lib/adva/static/rack/watch.rb +88 -0
- data/lib/adva/static/rack.rb +15 -0
- data/lib/adva/static/setup.rb +68 -0
- data/lib/adva/static/watch/handler.rb +57 -0
- data/lib/adva/static/watch.rb +7 -0
- data/lib/adva/static.rb +13 -0
- data/lib/adva/tasks/static.rb +73 -0
- data/lib/adva-static.rb +1 -0
- data/lib/testing/step_definitions.rb +85 -0
- data/lib/testing/test_helper.rb +133 -0
- metadata +151 -0
@@ -0,0 +1,92 @@
|
|
1
|
+
module Adva
|
2
|
+
class Static
|
3
|
+
class Import
|
4
|
+
class Request
|
5
|
+
attr_reader :source, :record, :attributes
|
6
|
+
|
7
|
+
def initialize(source, record, attributes)
|
8
|
+
@source = source
|
9
|
+
@record = record
|
10
|
+
@attributes = attributes
|
11
|
+
end
|
12
|
+
|
13
|
+
def params
|
14
|
+
@params ||= begin
|
15
|
+
key = model_name.underscore.to_sym
|
16
|
+
if destroy?
|
17
|
+
params = { '_method' => 'delete', key => { :id => record.id } }
|
18
|
+
else
|
19
|
+
params = { model_name.underscore.to_sym => attributes }
|
20
|
+
params.merge!('_method' => 'put') if update?
|
21
|
+
end
|
22
|
+
stringify(params)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def path
|
27
|
+
controller.polymorphic_path(controller.resources)
|
28
|
+
end
|
29
|
+
|
30
|
+
def public_path
|
31
|
+
controller.public_url_for(controller.resources, :routing_type => :path)
|
32
|
+
end
|
33
|
+
|
34
|
+
def create?
|
35
|
+
!update? && !destroy?
|
36
|
+
end
|
37
|
+
|
38
|
+
def update?
|
39
|
+
record.persisted? && source.exist?
|
40
|
+
end
|
41
|
+
|
42
|
+
def destroy?
|
43
|
+
record.persisted? && !source.exist?
|
44
|
+
end
|
45
|
+
|
46
|
+
def controller
|
47
|
+
@controller ||= controller_name.constantize.new.tap do |controller|
|
48
|
+
controller.request = ActionDispatch::TestRequest.new
|
49
|
+
controller.params = params_for(controller)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
protected
|
54
|
+
|
55
|
+
def section_ids
|
56
|
+
@section_ids ||= Section.types.map { |type| :"#{type.underscore}_id" }
|
57
|
+
end
|
58
|
+
|
59
|
+
def model_name
|
60
|
+
record.class.name
|
61
|
+
end
|
62
|
+
|
63
|
+
def controller_name
|
64
|
+
"Admin::#{model_name.pluralize}Controller"
|
65
|
+
end
|
66
|
+
|
67
|
+
def params_for(controller)
|
68
|
+
names = controller.send(:symbols_for_association_chain).dup
|
69
|
+
names.map! { |name| :"#{name}_id" }
|
70
|
+
names << :id unless record.new_record?
|
71
|
+
|
72
|
+
names.inject(:action => record.new_record? ? :index : :show) do |params, name|
|
73
|
+
# umm. admin blog routes use :blog_id, but Post has a section_id
|
74
|
+
value = attributes[section_ids.include?(name) ? :section_id : name].to_s
|
75
|
+
params.merge(name => value)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def stringify(object)
|
80
|
+
case object
|
81
|
+
when Hash
|
82
|
+
object.each { |key, value| object[key] = stringify(value) }
|
83
|
+
when Array
|
84
|
+
object.map! { |element| stringify(element) }
|
85
|
+
else
|
86
|
+
object.to_s
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
module Adva
|
2
|
+
class Static
|
3
|
+
class Import
|
4
|
+
class Source < Pathname
|
5
|
+
TYPES = ['html', 'jekyll', 'yml']
|
6
|
+
EXTENSIONS = TYPES.map { |type| ".#{type}" }
|
7
|
+
|
8
|
+
attr_reader :root
|
9
|
+
|
10
|
+
delegate :exist?, :to => :full_path
|
11
|
+
|
12
|
+
def initialize(path, root = nil)
|
13
|
+
root ||= path.root if path.respond_to?(:root)
|
14
|
+
@root = Pathname.new(root.to_s)
|
15
|
+
|
16
|
+
path = path.to_s.gsub(root, '') if root
|
17
|
+
path = path.to_s[1..-1] if path.to_s[0, 1] == '/'
|
18
|
+
super(path)
|
19
|
+
end
|
20
|
+
|
21
|
+
def find_or_self
|
22
|
+
find or self
|
23
|
+
end
|
24
|
+
|
25
|
+
def find
|
26
|
+
file = Dir["#{root.join(path)}.{#{TYPES.join(',')}}"].first
|
27
|
+
Source.new(file, root) if file
|
28
|
+
end
|
29
|
+
|
30
|
+
def all
|
31
|
+
@all ||= Dir[root.join(path).join("**/*.{#{TYPES.join(',')}}")].map { |path| Source.new(path, root) }
|
32
|
+
end
|
33
|
+
|
34
|
+
def files
|
35
|
+
files = path == 'index' ? directory.all : all
|
36
|
+
files.reject { |path| path.basename == 'site' }.sort
|
37
|
+
end
|
38
|
+
|
39
|
+
def root?
|
40
|
+
@_root ||= path == 'index' || full_path.to_s == root.to_s
|
41
|
+
end
|
42
|
+
|
43
|
+
def directory
|
44
|
+
@directory ||= self.class.new(dirname, root)
|
45
|
+
end
|
46
|
+
|
47
|
+
def basename
|
48
|
+
@basename ||= super.to_s.sub(/\.\w+$/, '')
|
49
|
+
end
|
50
|
+
|
51
|
+
def dirname
|
52
|
+
@dirname ||= super.to_s.sub(/^.$/, '')
|
53
|
+
end
|
54
|
+
|
55
|
+
def path
|
56
|
+
@_path ||= [dirname, basename].select(&:present?).join('/')
|
57
|
+
end
|
58
|
+
|
59
|
+
def full_path
|
60
|
+
@full_path ||= root.join(self)
|
61
|
+
end
|
62
|
+
|
63
|
+
def self_and_parents
|
64
|
+
parents << self
|
65
|
+
end
|
66
|
+
|
67
|
+
def parents
|
68
|
+
@parents ||= begin
|
69
|
+
parts = self.to_s.split('/')[0..-2]
|
70
|
+
parts.inject([]) do |parents, part|
|
71
|
+
parents << Source.new(parts[0..parents.size].join('/'), root)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def <=>(other)
|
77
|
+
path == 'index' ? -1 : other.path == 'index' ? 1 : path <=> other.path
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module Adva
|
2
|
+
class Static
|
3
|
+
class Import
|
4
|
+
autoload :Format, 'adva/static/import/format'
|
5
|
+
autoload :Model, 'adva/static/import/model'
|
6
|
+
autoload :Request, 'adva/static/import/request'
|
7
|
+
autoload :Source, 'adva/static/import/source'
|
8
|
+
|
9
|
+
attr_reader :root
|
10
|
+
|
11
|
+
def initialize(options = {})
|
12
|
+
@root = Pathname.new(File.expand_path(options[:source] || 'import'))
|
13
|
+
end
|
14
|
+
|
15
|
+
def run
|
16
|
+
Adva.out.puts "importing from #{root}"
|
17
|
+
Account.all.each(&:destroy)
|
18
|
+
Model::Site.new(root).updated_record.save!
|
19
|
+
end
|
20
|
+
|
21
|
+
def import(path)
|
22
|
+
model = recognize(path).first
|
23
|
+
model.updated_record.save! if model
|
24
|
+
end
|
25
|
+
|
26
|
+
def request_for(path)
|
27
|
+
model = recognize(path).first
|
28
|
+
Request.new(model.source, model.record, model.attributes)
|
29
|
+
end
|
30
|
+
|
31
|
+
protected
|
32
|
+
|
33
|
+
def source(path)
|
34
|
+
Source.new(path, root)
|
35
|
+
end
|
36
|
+
|
37
|
+
def recognize(path)
|
38
|
+
Model.recognize([source(path)])
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
|
3
|
+
module Adva
|
4
|
+
class Static
|
5
|
+
module Rack
|
6
|
+
class Export
|
7
|
+
include Request
|
8
|
+
|
9
|
+
attr_reader :app, :target, :store
|
10
|
+
|
11
|
+
def initialize(app, options = {})
|
12
|
+
@app = app
|
13
|
+
@target = Pathname.new(options[:target] || File.expand_path('./export'))
|
14
|
+
@store = Adva::Static::Export::Store.new(target)
|
15
|
+
end
|
16
|
+
|
17
|
+
def call(env)
|
18
|
+
path = env['PATH_INFO'].dup # gets modified by routing_filter
|
19
|
+
app.call(env).tap do |status, headers, response|
|
20
|
+
export(path, response) if export?(env, status)
|
21
|
+
if headers.key?(PURGE_HEADER)
|
22
|
+
paths = normalize_paths(headers[PURGE_HEADER])
|
23
|
+
paths.each do |path|
|
24
|
+
purge(path)
|
25
|
+
request(path)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
protected
|
32
|
+
|
33
|
+
def export?(env, status)
|
34
|
+
env[STORE_HEADER].present? and status == 200
|
35
|
+
end
|
36
|
+
|
37
|
+
def export(path, response)
|
38
|
+
page = Adva::Static::Export::Page.new(path, response)
|
39
|
+
Adva.out.puts " storing #{page.url.filename}"
|
40
|
+
store.write(page.url, page.body)
|
41
|
+
end
|
42
|
+
|
43
|
+
def purge(path)
|
44
|
+
Adva.out.puts " purging #{path}"
|
45
|
+
store.purge(Adva::Static::Export::Path.new(path))
|
46
|
+
end
|
47
|
+
|
48
|
+
def request(path)
|
49
|
+
super('GET', Adva::Static::Export::Path.new(path), STORE_HEADER => true)
|
50
|
+
end
|
51
|
+
|
52
|
+
def normalize_paths(paths)
|
53
|
+
paths = paths.split("\n") if paths.is_a?(String)
|
54
|
+
Array(paths)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'rack/utils'
|
2
|
+
|
3
|
+
module Adva
|
4
|
+
class Static
|
5
|
+
module Rack
|
6
|
+
module Request
|
7
|
+
protected
|
8
|
+
def request(method, path, params = {})
|
9
|
+
Adva.out.puts " #{params['_method'] ? params['_method'].upcase : method} #{path} "
|
10
|
+
call(env_for(method, path, params)).tap do |status, headers, response|
|
11
|
+
Adva.out.puts " => #{status} " + (status == 302 ? "(Location: #{headers['Location']})" : '')
|
12
|
+
Adva.out.puts response if status == 500
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def env_for(method, path, params)
|
17
|
+
::Rack::MockRequest.env_for("http://#{site.host}#{path}", :method => method,
|
18
|
+
:input => ::Rack::Utils.build_nested_query(params),
|
19
|
+
'CONTENT_TYPE' => 'application/x-www-form-urlencoded',
|
20
|
+
'HTTP_AUTHORIZATION' => 'Basic ' + ["#{username}:#{password}"].pack('m*'),
|
21
|
+
STORE_HEADER => params[STORE_HEADER]
|
22
|
+
)
|
23
|
+
end
|
24
|
+
|
25
|
+
def username
|
26
|
+
'admin@admin.org' # TODO read from conf/auth.yml or something
|
27
|
+
end
|
28
|
+
|
29
|
+
def password
|
30
|
+
'admin!'
|
31
|
+
end
|
32
|
+
|
33
|
+
def site
|
34
|
+
@site ||= Site.first || raise('could not find any site') # FIXME
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'rack/utils'
|
2
|
+
|
3
|
+
module Adva
|
4
|
+
class Static
|
5
|
+
module Rack
|
6
|
+
class Static < ::Rack::File
|
7
|
+
attr_reader :app, :root
|
8
|
+
|
9
|
+
def initialize(app, root)
|
10
|
+
@app = app
|
11
|
+
@root = root
|
12
|
+
Adva.out.puts "serving from #{root}"
|
13
|
+
end
|
14
|
+
|
15
|
+
def call(env)
|
16
|
+
if get?(env) && path = static(env)
|
17
|
+
super(env.merge('PATH_INFO' => path))
|
18
|
+
else
|
19
|
+
app.call(env)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
protected
|
24
|
+
|
25
|
+
def static(env)
|
26
|
+
path = env['PATH_INFO'].chomp('/')
|
27
|
+
[path, "#{path}.html", "#{path}/index.html"].detect { |path| file?(path) }
|
28
|
+
end
|
29
|
+
|
30
|
+
def file?(path)
|
31
|
+
File.file?(File.join(root, ::Rack::Utils.unescape(path)))
|
32
|
+
end
|
33
|
+
|
34
|
+
def get?(env)
|
35
|
+
env['REQUEST_METHOD'] == 'GET'
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
require 'watchr'
|
2
|
+
|
3
|
+
module Adva
|
4
|
+
class Static
|
5
|
+
module Rack
|
6
|
+
class Watch
|
7
|
+
autoload :Handler, 'adva/static/watch/handler'
|
8
|
+
|
9
|
+
include Request
|
10
|
+
|
11
|
+
attr_reader :app, :dir, :watch
|
12
|
+
|
13
|
+
delegate :call, :to => :app
|
14
|
+
|
15
|
+
def initialize(app, options = {}, &block)
|
16
|
+
@app = app
|
17
|
+
@dir = Pathname.new(options[:dir] || File.expand_path('import'))
|
18
|
+
dir.mkpath
|
19
|
+
run!
|
20
|
+
end
|
21
|
+
|
22
|
+
def update(path, event_type = nil)
|
23
|
+
Adva.out.puts "\n#{event_type}: #{path}"
|
24
|
+
import = Adva::Static::Import.new(:source => dir)
|
25
|
+
request = import.request_for(path)
|
26
|
+
status, headers, response = self.request('POST', request.path, request.params)
|
27
|
+
get(path) if !request.destroy? && status == 302
|
28
|
+
rescue Exception => e
|
29
|
+
Adva.out.puts e.message
|
30
|
+
e.backtrace.each { |line| puts Adva.out.line }
|
31
|
+
end
|
32
|
+
|
33
|
+
def get(path)
|
34
|
+
import = Adva::Static::Import.new(:source => dir)
|
35
|
+
request = import.request_for(path)
|
36
|
+
self.request('GET', request.public_path, STORE_HEADER => true)
|
37
|
+
rescue Exception => e
|
38
|
+
Adva.out.puts e.message
|
39
|
+
e.backtrace.each { |line| Adva.out.puts line }
|
40
|
+
end
|
41
|
+
|
42
|
+
protected
|
43
|
+
|
44
|
+
def run!
|
45
|
+
@watch = fork { watch!(Adva.out) }
|
46
|
+
at_exit { kill_watch }
|
47
|
+
end
|
48
|
+
|
49
|
+
def watch!(out)
|
50
|
+
Adva.out.puts "watching #{dir} for changes"
|
51
|
+
Dir.chdir(dir)
|
52
|
+
handler.listen
|
53
|
+
rescue SignalException, SystemExit
|
54
|
+
rescue Exception => e
|
55
|
+
p e
|
56
|
+
e.backtrace.each { |line| puts line }
|
57
|
+
end
|
58
|
+
|
59
|
+
def trap_interrupt
|
60
|
+
Signal.trap('INT') do
|
61
|
+
if Time.now - @interrupt < 1
|
62
|
+
exit
|
63
|
+
else
|
64
|
+
STDERR.puts "\nReloading watched paths ... interrupt again to exit."
|
65
|
+
handler.refresh(watched_paths)
|
66
|
+
end
|
67
|
+
@interrupt = Time.now
|
68
|
+
end
|
69
|
+
@interrupt = Time.now
|
70
|
+
end
|
71
|
+
|
72
|
+
def handler
|
73
|
+
@handler ||= Adva::Static::Watch::Handler.new(self, dir.join("**/*.{#{Import::Source::TYPES.join(',')}}"))
|
74
|
+
end
|
75
|
+
|
76
|
+
def kill_watch
|
77
|
+
Process.kill('TERM', watch)
|
78
|
+
end
|
79
|
+
|
80
|
+
def watched_paths
|
81
|
+
paths = Dir[dir.join('**/*')].map {|path| Pathname(path).expand_path }
|
82
|
+
paths << Pathname.new(__FILE__) if paths.empty?
|
83
|
+
paths
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'adva'
|
2
|
+
|
3
|
+
module Adva
|
4
|
+
class Static
|
5
|
+
module Rack
|
6
|
+
PURGE_HEADER = 'rack-cache.purge'
|
7
|
+
STORE_HEADER = 'rack-static.store'
|
8
|
+
|
9
|
+
autoload :Request, 'adva/static/rack/request'
|
10
|
+
autoload :Export, 'adva/static/rack/export'
|
11
|
+
autoload :Static, 'adva/static/rack/static'
|
12
|
+
autoload :Watch, 'adva/static/rack/watch'
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require 'core_ext/ruby/kernel/silence_stream'
|
2
|
+
|
3
|
+
module Adva
|
4
|
+
class Static
|
5
|
+
class Setup
|
6
|
+
attr_reader :app, :root, :source, :target, :host, :title, :remote
|
7
|
+
|
8
|
+
def initialize(options)
|
9
|
+
@app = options[:app] || Rails.application
|
10
|
+
@root = Pathname.new(options[:root] || Dir.pwd)
|
11
|
+
@source = root.join(options[:source] || 'import')
|
12
|
+
@target = root.join(options[:target] || 'export')
|
13
|
+
@remote = options[:remote]
|
14
|
+
@host = options[:host] || 'example.org'
|
15
|
+
@title = options[:title] || host
|
16
|
+
|
17
|
+
Adva.out = StringIO.new('')
|
18
|
+
end
|
19
|
+
|
20
|
+
def run
|
21
|
+
setup_directories
|
22
|
+
initial_import_and_export
|
23
|
+
setup_source_repository
|
24
|
+
setup_export_repository
|
25
|
+
end
|
26
|
+
|
27
|
+
def setup_directories
|
28
|
+
source.mkdir rescue Errno::EEXIST
|
29
|
+
target.mkdir rescue Errno::EEXIST
|
30
|
+
site = source.join('site.yml')
|
31
|
+
File.open(site, 'w+') { |f| f.write(YAML.dump(:host => host, :title => title)) } unless site.exist?
|
32
|
+
end
|
33
|
+
|
34
|
+
def initial_import_and_export
|
35
|
+
Import.new(:source => source).run
|
36
|
+
Export.new(app, :target => target).run
|
37
|
+
end
|
38
|
+
|
39
|
+
def setup_source_repository
|
40
|
+
root.join('.gitignore').rmtree rescue Errno::ENOENT
|
41
|
+
root.join('.git').rmtree rescue Errno::ENOENT
|
42
|
+
|
43
|
+
File.open(root.join('.gitignore'), 'w+') { |f| f.write('export') }
|
44
|
+
|
45
|
+
Dir.chdir(root) do
|
46
|
+
`git init`
|
47
|
+
`git add .`
|
48
|
+
`git commit -am '#{host} source'`
|
49
|
+
`git branch source`
|
50
|
+
`git checkout --quiet source`
|
51
|
+
`git branch -D master`
|
52
|
+
`git remote add origin #{remote} -t source` if remote
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def setup_export_repository
|
57
|
+
root.join('export/.git').rmtree rescue Errno::ENOENT
|
58
|
+
|
59
|
+
Dir.chdir(target) do
|
60
|
+
`git init`
|
61
|
+
`git add .`
|
62
|
+
`git commit -am '#{host} export'`
|
63
|
+
`git remote add origin #{remote} -t master` if remote
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'observer'
|
2
|
+
require 'watchr'
|
3
|
+
require 'watchr/event_handlers/portable'
|
4
|
+
|
5
|
+
module Adva
|
6
|
+
class Static
|
7
|
+
module Watch
|
8
|
+
class Handler
|
9
|
+
include Observable
|
10
|
+
|
11
|
+
def initialize(observable, pattern)
|
12
|
+
add_observer(observable)
|
13
|
+
@pattern = pattern
|
14
|
+
@current = Dir[pattern]
|
15
|
+
@mtime = Time.now
|
16
|
+
end
|
17
|
+
|
18
|
+
def listen
|
19
|
+
loop { trigger; sleep(0.5) }
|
20
|
+
end
|
21
|
+
|
22
|
+
def trigger
|
23
|
+
events.each do |path, event|
|
24
|
+
changed(true)
|
25
|
+
notify_observers(path, event)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
protected
|
30
|
+
|
31
|
+
def events
|
32
|
+
@last = @current.dup
|
33
|
+
@current = Dir[@pattern]
|
34
|
+
deleted + created + modified
|
35
|
+
end
|
36
|
+
|
37
|
+
def modified
|
38
|
+
(@current & @last).each do |path|
|
39
|
+
mtime = File.mtime(path)
|
40
|
+
if mtime > @mtime
|
41
|
+
@mtime = mtime
|
42
|
+
return [[path, :modified]]
|
43
|
+
end
|
44
|
+
end && []
|
45
|
+
end
|
46
|
+
|
47
|
+
def created
|
48
|
+
(@current - @last).map { |path| [path, :created] }
|
49
|
+
end
|
50
|
+
|
51
|
+
def deleted
|
52
|
+
(@last - @current).map { |path| [path, :deleted] }
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
data/lib/adva/static.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'adva'
|
2
|
+
|
3
|
+
module Adva
|
4
|
+
class Static < ::Rails::Engine
|
5
|
+
autoload :Export, 'adva/static/export'
|
6
|
+
autoload :Import, 'adva/static/import'
|
7
|
+
autoload :Watch, 'adva/static/watch'
|
8
|
+
autoload :Rack, 'adva/static/rack'
|
9
|
+
autoload :Setup, 'adva/static/setup'
|
10
|
+
|
11
|
+
include Adva::Engine
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
require 'thor'
|
2
|
+
require 'thor/group'
|
3
|
+
require 'patches/thor/core_ext/hash'
|
4
|
+
require 'patches/thor/group/symbolized_options'
|
5
|
+
|
6
|
+
module Adva
|
7
|
+
module Tasks
|
8
|
+
class Static
|
9
|
+
class Setup < Thor::Group
|
10
|
+
namespace 'adva:static:setup'
|
11
|
+
desc 'Setup a static version of your site'
|
12
|
+
class_option :source, :required => false, :banner => 'source directory (defaults to import)'
|
13
|
+
class_option :target, :required => false, :banner => 'source directory (defaults to export)'
|
14
|
+
class_option :host, :required => false, :banner => 'hostname of your site (defaults to example.org)'
|
15
|
+
class_option :title, :required => false, :banner => 'title of your site (defaults to the hostname)'
|
16
|
+
class_option :remote, :required => false, :banner => 'github repository url (defaults to none)'
|
17
|
+
|
18
|
+
def export
|
19
|
+
require 'config/environment'
|
20
|
+
Adva::Static::Setup.new(symbolized_options).run
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
class Import < Thor::Group
|
25
|
+
namespace 'adva:static:import'
|
26
|
+
desc 'Import a site from a directory'
|
27
|
+
class_option :source, :required => false
|
28
|
+
|
29
|
+
def import
|
30
|
+
require 'config/environment'
|
31
|
+
Adva::Static::Import.new(symbolized_options).run
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
class Export < Thor::Group
|
36
|
+
namespace 'adva:static:export'
|
37
|
+
desc 'Export a static version of a site'
|
38
|
+
class_option :target, :required => false
|
39
|
+
|
40
|
+
def export
|
41
|
+
require 'config/environment'
|
42
|
+
Adva::Static::Export.new(Rails.application, symbolized_options).run
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
class Update < Thor::Group
|
47
|
+
namespace 'adva:static:update'
|
48
|
+
desc 'Import and export a static version of a site'
|
49
|
+
class_option :source, :required => false
|
50
|
+
class_option :target, :required => false
|
51
|
+
|
52
|
+
def export
|
53
|
+
require 'config/environment'
|
54
|
+
Adva::Static::Import.new(symbolized_options).run
|
55
|
+
Adva::Static::Export.new(Rails.application, symbolized_options).run
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
class Server < Thor::Group
|
60
|
+
namespace 'adva:static:server'
|
61
|
+
desc 'Start the adva:static server and watcher'
|
62
|
+
class_option :root, :required => false, :default => 'export'
|
63
|
+
|
64
|
+
def server
|
65
|
+
ARGV.shift
|
66
|
+
Dir.chdir(symbolized_options[:root])
|
67
|
+
require "rack"
|
68
|
+
::Rack::Server.start
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
data/lib/adva-static.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'adva/static'
|