adva-static 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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'
|