adva-static 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,118 @@
1
+ require 'pathname'
2
+
3
+ # Bundler gemfile support for local/remote workspaces/repositories for work in
4
+ # development teams.
5
+ #
6
+ # Usage:
7
+ #
8
+ # # define paths to be searched for repositories:
9
+ # workspace '~/.projects ~/Development/{projects,work}'
10
+ #
11
+ # # define developer preferences for using local or remote repositories (uses ENV['user']):
12
+ # developer :sven, :prefer => :local
13
+ #
14
+ # # define repositories to be used for particular gems:
15
+ # adva_cms = repository('adva-cms2', :git => 'git@github.com:svenfuchs/adva-cms2.git', :ref => 'c2af0de')
16
+ # adva_shop = repository('adva-shop', :source => :local)
17
+ #
18
+ # # now use repositories to define gems:
19
+ # adva_cms.gem 'adva-core'
20
+ # adva_shop.gem 'adva-catalog'
21
+ #
22
+ # # The gem definition will now be proxied to Bundler with arguments according
23
+ # # to the setup defined earlier. E.g. as:
24
+ #
25
+ # gem 'adva-core', :path => 'Development/projects/adva-cms2/adva-core' # for developer 'sven'
26
+ # gem 'adva-core', :git => 'git@github.com:svenfuchs/adva-cms2.git', :ref => 'c2af0de' # for other developers
27
+ # gem 'adva-catalog', :path => 'Development/projects/adva-shop/adva-catalog' # for all developers
28
+ #
29
+ # One can also set an environment variable FORCE_REMOTE which will force remote
30
+ # repositories to be used *except* when a repository was defined with :source => :local
31
+ # which always forces the local repository to be used.
32
+ #
33
+ class Repository
34
+ class << self
35
+ def paths
36
+ @paths ||= []
37
+ end
38
+
39
+ def path(*paths)
40
+ paths.join(' ').split(' ').each do |path|
41
+ self.paths.concat(Pathname.glob(File.expand_path(path)))
42
+ end
43
+ end
44
+
45
+ def developer(name, preferences)
46
+ developers[name] = preferences
47
+ workspaces(preferences[:workspace])
48
+ end
49
+
50
+ def current_developer
51
+ developers[ENV['USER'].to_sym] || {}
52
+ end
53
+
54
+ def developers(developers = nil)
55
+ @developers ||= {}
56
+ end
57
+ end
58
+
59
+ class Gem < Array
60
+ def initialize(name, repository)
61
+ if repository.local?
62
+ sub_path = repository.path.join(name)
63
+ super([name, { :path => sub_path.exist? ? sub_path.to_s : repository.path.to_s }])
64
+ else
65
+ super([name, repository.options.dup])
66
+ end
67
+ end
68
+ end
69
+
70
+ attr_reader :bundler, :name, :options, :source
71
+
72
+ def initialize(bundler, name, options)
73
+ @bundler = bundler
74
+ @name = name
75
+ @source = options.delete(:source)
76
+ @options = options
77
+ end
78
+
79
+ def gem(name)
80
+ bundler.gem(*Gem.new(name, self))
81
+ end
82
+
83
+ def local?
84
+ source == :local # && path
85
+ end
86
+
87
+ def source
88
+ @source ||= forced_source || preferred_source || :remote
89
+ end
90
+
91
+ def forced_source
92
+ :remote if ENV['FORCE_REMOTE']
93
+ end
94
+
95
+ def preferred_source
96
+ self.class.current_developer[:prefer] || self.class.current_developer[name.to_sym]
97
+ end
98
+
99
+ def path
100
+ @path ||= begin
101
+ path = self.class.paths.detect { |path| path.join(name).exist? }
102
+ path ? path.join(name) : Pathname.new('.')
103
+ end
104
+ end
105
+ end
106
+
107
+ def workspace(*paths)
108
+ Repository.path(*paths)
109
+ end
110
+ alias :workspaces :workspace
111
+
112
+ def developer(name, preferences)
113
+ Repository.developer(name, preferences)
114
+ end
115
+
116
+ def repository(*args)
117
+ Repository.new(self, *args)
118
+ end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: adva-static
3
3
  version: !ruby/object:Gem::Version
4
- hash: 27
4
+ hash: 25
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 2
10
- version: 0.0.2
9
+ - 3
10
+ version: 0.0.3
11
11
  platform: ruby
12
12
  authors:
13
13
  - Sven Fuchs
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-11-08 00:00:00 +01:00
18
+ date: 2010-11-19 00:00:00 +01:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -83,37 +83,7 @@ extensions: []
83
83
  extra_rdoc_files: []
84
84
 
85
85
  files:
86
- - lib/adva_static/version.rb
87
- - lib/adva-static.rb
88
- - lib/adva/tasks/static.rb
89
- - lib/adva/static/setup.rb
90
- - lib/adva/static/export.rb
91
- - lib/adva/static/import/format.rb
92
- - lib/adva/static/import/source.rb
93
- - lib/adva/static/import/model.rb
94
- - lib/adva/static/import/model/page.rb
95
- - lib/adva/static/import/model/site.rb
96
- - lib/adva/static/import/model/post.rb
97
- - lib/adva/static/import/model/section.rb
98
- - lib/adva/static/import/model/base.rb
99
- - lib/adva/static/import/model/blog.rb
100
- - lib/adva/static/import/request.rb
101
- - lib/adva/static/watch.rb
102
- - lib/adva/static/export/page.rb
103
- - lib/adva/static/export/templates/config.ru
104
- - lib/adva/static/export/path.rb
105
- - lib/adva/static/export/store.rb
106
- - lib/adva/static/export/queue.rb
107
- - lib/adva/static/rack/export.rb
108
- - lib/adva/static/rack/watch.rb
109
- - lib/adva/static/rack/static.rb
110
- - lib/adva/static/rack/request.rb
111
- - lib/adva/static/rack.rb
112
- - lib/adva/static/watch/handler.rb
113
- - lib/adva/static/import.rb
114
- - lib/adva/static.rb
115
- - lib/testing/test_helper.rb
116
- - lib/testing/step_definitions.rb
86
+ - lib/bundler/repository.rb
117
87
  has_rdoc: true
118
88
  homepage: http://github.com/svenfuchs/adva-cms2
119
89
  licenses: []
@@ -1 +0,0 @@
1
- require 'adva/static'
@@ -1,13 +0,0 @@
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
@@ -1,104 +0,0 @@
1
- require 'nokogiri'
2
- require 'uri'
3
- require 'benchmark'
4
-
5
- module Adva
6
- class Static
7
- class Export
8
- autoload :Page, 'adva/static/export/page'
9
- autoload :Path, 'adva/static/export/path'
10
- autoload :Queue, 'adva/static/export/queue'
11
- autoload :Store, 'adva/static/export/store'
12
-
13
- attr_reader :app, :queue, :store, :options
14
-
15
- DEFAULT_OPTIONS = {
16
- :source => "#{Dir.pwd}/public",
17
- :target => "#{Dir.pwd}/export"
18
- }
19
-
20
- def initialize(app, options = {})
21
- @options = options.reverse_merge!(DEFAULT_OPTIONS)
22
-
23
- @app = app
24
- @store = Store.new(target)
25
- @queue = Queue.new
26
-
27
- queue.push(options[:queue] || Path.new('/'))
28
-
29
- FileUtils.rm_r(Dir[target.join('*')])
30
- end
31
-
32
- def run
33
- configure
34
- copy_assets
35
- process(queue.shift) until queue.empty?
36
- end
37
-
38
- protected
39
-
40
- def source
41
- @source ||= Pathname.new(options[:source])
42
- end
43
-
44
- def target
45
- @target ||= Pathname.new(options[:target])
46
- end
47
-
48
- def copy_assets
49
- %w(images javascripts stylesheets).each do |dir|
50
- FileUtils.cp_r(source.join(dir), target.join(dir)) if source.join(dir).exist?
51
- end
52
- end
53
-
54
- def process(path)
55
- if page = get(path)
56
- store.write(path, page.body)
57
- enqueue_urls(page) if path.html?
58
- end
59
- end
60
-
61
- def get(path)
62
- result = nil
63
- bench = Benchmark.measure do
64
- result = app.call(env_for(path))
65
- result = follow_redirects(result)
66
- end
67
-
68
- status, headers, response = result
69
- if status == 200
70
- Adva.out.puts "#{bench.total.to_s[0..3]}s: exporting #{path}"
71
- Page.new(path, headers['X-Sendfile'] ? File.read(headers['X-Sendfile']) : response)
72
- else
73
- Adva.out.puts "can not export #{path} (status: #{status})"
74
- end
75
- end
76
-
77
- def follow_redirects(response)
78
- response = app.call(env_for(response[1]['Location'])) while redirect?(response[0])
79
- response
80
- end
81
-
82
- def redirect?(status)
83
- status == 301
84
- end
85
-
86
- def env_for(path)
87
- site = Site.first || raise('could not find any site') # TODO make this a cmd line arg or options
88
- name, port = site.host.split(':')
89
- ::Rack::MockRequest.env_for(path).merge('SERVER_NAME' => name,'SERVER_PORT' => port || '80')
90
- end
91
-
92
- def enqueue_urls(page)
93
- queue.push(page.urls.reject { |path| path.remote? || store.exists?(path) }.uniq)
94
- end
95
-
96
- def configure
97
- config = Path.new('config.ru')
98
- unless store.exists?(config)
99
- store.write(config, File.read(File.expand_path('../export/templates/config.ru', __FILE__)))
100
- end
101
- end
102
- end
103
- end
104
- end
@@ -1,45 +0,0 @@
1
- require 'rack'
2
-
3
- module Adva
4
- class Static
5
- class Export
6
- class Page
7
- URL_ATTRIBUTES = {
8
- '//a[@href]' => 'href',
9
- '//script[@src]' => 'src',
10
- '//link[@rel="stylesheet"]' => 'href'
11
- }
12
-
13
- attr_reader :url, :response
14
-
15
- def initialize(url, response)
16
- @url = Path.new(url)
17
- @response = response
18
- end
19
-
20
- def urls
21
- URL_ATTRIBUTES.inject([]) do |urls, (xpath, name)|
22
- urls += dom.xpath(xpath).map { |node| Path.new(node.attributes[name]) }
23
- end
24
- end
25
-
26
- def body
27
- @body ||= case response
28
- when ActionDispatch::Response
29
- response.body
30
- when ::Rack::File
31
- File.read(response.path)
32
- else
33
- response.to_s
34
- end
35
- end
36
-
37
- protected
38
-
39
- def dom
40
- @dom ||= Nokogiri::HTML(body)
41
- end
42
- end
43
- end
44
- end
45
- end
@@ -1,49 +0,0 @@
1
- require 'uri'
2
-
3
- module Adva
4
- class Static
5
- class Export
6
- class Path < String
7
- attr_reader :host
8
-
9
- def initialize(path)
10
- @host = URI.parse(path.to_s).host rescue 'invalid.host'
11
- path = normalize_path(path)
12
- super
13
- end
14
-
15
- def filename
16
- @filename ||= normalize_filename(self)
17
- end
18
-
19
- def extname
20
- @extname ||= File.extname(self)
21
- end
22
-
23
- def html?
24
- extname.blank? || extname == '.html'
25
- end
26
-
27
- def remote?
28
- host.present?
29
- end
30
-
31
- protected
32
-
33
- def normalize_path(path)
34
- path = URI.parse(path.to_s).path || '/' rescue '/' # extract path
35
- path = path[0..-2] if path[-1, 1] == '/' # remove trailing slash
36
- path = "/#{path}" unless path[0, 1] == '/' # add leading slash
37
- path
38
- end
39
-
40
- def normalize_filename(path)
41
- path = path[1..-1] if path[0, 1] == '/' # remove leading slash
42
- path = 'index' if path.empty? # use 'index' instead of empty paths
43
- path = (html? ? "#{path.gsub(extname, '')}.html" : path) # add .html extension if necessary
44
- path
45
- end
46
- end
47
- end
48
- end
49
- end
@@ -1,27 +0,0 @@
1
- module Adva
2
- class Static
3
- class Export
4
- class Queue < Array
5
- def push(*elements)
6
- elements = Array(elements).flatten.uniq
7
- elements.reject! { |element| seen?(element) }
8
- seen(elements)
9
- super
10
- end
11
-
12
- def seen?(element)
13
- log.include?(element)
14
- end
15
-
16
- def seen(elements)
17
- @log = log.concat(elements)
18
- log.uniq!
19
- end
20
-
21
- def log
22
- @log ||= []
23
- end
24
- end
25
- end
26
- end
27
- end
@@ -1,30 +0,0 @@
1
- require 'fileutils'
2
-
3
- module Adva
4
- class Static
5
- class Export
6
- class Store
7
- attr_reader :dir
8
-
9
- def initialize(dir)
10
- @dir = Pathname.new(dir.to_s)
11
- FileUtils.mkdir_p(dir)
12
- end
13
-
14
- def exists?(path)
15
- File.exists?(dir.join(path.filename))
16
- end
17
-
18
- def write(path, body)
19
- path = dir.join(path.filename)
20
- FileUtils.mkdir_p(File.dirname(path))
21
- File.open(path, 'w+') { |f| f.write(body) }
22
- end
23
-
24
- def purge(path)
25
- dir.join(path.filename).delete rescue Errno::ENOENT
26
- end
27
- end
28
- end
29
- end
30
- end