excursion 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 91ab81cf91d566addc17aa5963965138a1c6592a
4
+ data.tar.gz: 32aae702c9c69c58bbb4c420e606a50990e51d5f
5
+ SHA512:
6
+ metadata.gz: cb034cdfc374f4266221b176d3cf786981b7af4287446340530933ae097f9e8ba3f13df52b0bd7460a7bf3a1e5af72d241984a2df26c1674fdced47f6b98c376
7
+ data.tar.gz: eb5cfb2d550eee50c5b26db1ef89a5f188846dd3bebe29d46c89c430c219f3b3d58c16f6ecc10a02c78ac2769e5b8031a6f447b0b33eecca125d14917d4e8996
@@ -0,0 +1,86 @@
1
+ module Excursion
2
+ class Configuration
3
+ DEFAULT_CONFIGURATION_OPTIONS = {
4
+ # TODO
5
+ # exclude_pattern: to exclude certain routes from being shared
6
+ # include_pattern: to only include certain routes
7
+ default_url_options: {}
8
+ }
9
+
10
+ #attr_reader *DEFAULT_CONFIGURATION_OPTIONS.keys
11
+
12
+ #DEFAULT_CONFIGURATION_OPTIONS.keys.each do |key|
13
+ # define_method "#{key.to_s}=" do |val|
14
+ # @changed[key] = [send(key), val]
15
+ # instance_variable_set "@#{key.to_s}", val
16
+ # end
17
+ #end
18
+
19
+ def method_missing(meth, *args)
20
+ if meth.to_s.match(/\A(.*)=\Z/)
21
+ @changed[$1] = [send($1), *args]
22
+ instance_variable_set "@#{$1.to_s}", *args
23
+ else
24
+ instance_variable_get "@#{meth}"
25
+ end
26
+ end
27
+
28
+ # Returns a hash of all the changed keys and values after being reconfigured
29
+ def changed
30
+ @changed = {}
31
+ to_hash.each { |key,val| @changed[key] = [@saved_state[key], val] if @saved_state[key] != val }
32
+ @changed
33
+ end
34
+
35
+ # Check whether a key was changed after being reconfigured
36
+ def changed?(key)
37
+ changed.has_key?(key)
38
+ end
39
+
40
+ # Pass arguments and/or a block to configure the available options
41
+ def configure(args={}, &block)
42
+ save_state
43
+ configure_with_args args
44
+ configure_with_block &block if block_given?
45
+ self
46
+ end
47
+
48
+ # Accepts arguments which are used to configure available options
49
+ def configure_with_args(args)
50
+ args.select { |k,v| DEFAULT_CONFIGURATION_OPTIONS.keys.include?(k) }.each do |key,val|
51
+ instance_variable_set "@#{key.to_s}", val
52
+ end
53
+ end
54
+
55
+ # Accepts a block which is used to configure available options
56
+ def configure_with_block(&block)
57
+ self.instance_eval(&block) if block_given?
58
+ end
59
+
60
+ # Saves a copy of the current state, to be used later to determine what was changed
61
+ def save_state
62
+ @saved_state = clone.to_hash
63
+ @changed = {}
64
+ end
65
+
66
+ def to_hash
67
+ h = {}
68
+ DEFAULT_CONFIGURATION_OPTIONS.keys.each do |key|
69
+ h[key] = instance_variable_get "@#{key.to_s}"
70
+ end
71
+ h
72
+ end
73
+ alias_method :to_h, :to_hash
74
+
75
+ protected
76
+
77
+ def initialize
78
+ DEFAULT_CONFIGURATION_OPTIONS.each do |key,val|
79
+ instance_variable_set "@#{key.to_s}", val
80
+ end
81
+ save_state
82
+ super
83
+ end
84
+
85
+ end
86
+ end
@@ -0,0 +1,14 @@
1
+ module Excursion
2
+ module Datasources
3
+ class Datasource
4
+
5
+ def read(key); end
6
+ alias_method :get, :read
7
+ def write(key, value); end
8
+ alias_method :set, :write
9
+ def delete(key); end
10
+ alias_method :unset, :delete
11
+
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,53 @@
1
+ require 'yaml'
2
+ require 'excursion/datasources/datasource'
3
+
4
+ module Excursion
5
+ module Datasources
6
+ class File < Datasource
7
+
8
+ def read(key)
9
+ read_file[key.to_s]
10
+ end
11
+ alias_method :get, :read
12
+
13
+ def write(key, value)
14
+ current = read_file
15
+ current[key.to_s] = value
16
+ write_file(current)
17
+ current[key.to_s]
18
+ end
19
+ alias_method :set, :write
20
+
21
+ def delete(key)
22
+ current = read_file
23
+ deleted = current.delete(key.to_s)
24
+ write_file(current)
25
+ deleted
26
+ end
27
+ alias_method :unset, :delete
28
+
29
+ protected
30
+
31
+ def initialize(path=nil)
32
+ path = Excursion.configuration.datasource_file
33
+ @path = ::File.expand_path(path)
34
+ rescue
35
+ raise "Could not initialize the File datasource. Make sure you have properly configured your datasource"
36
+ end
37
+
38
+ def exists?
39
+ ::File.exists(@path)
40
+ end
41
+
42
+ def read_file
43
+ YAML.load_file(@path) || {}
44
+ rescue
45
+ {}
46
+ end
47
+
48
+ def write_file(results)
49
+ ::File.open(@path, 'w') { |f| f.write(results.to_yaml)}
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,24 @@
1
+ module Excursion
2
+ module Helpers
3
+ class ApplicationHelper
4
+
5
+ def routes
6
+ @application.routes
7
+ end
8
+
9
+ def method_missing(meth, *args)
10
+ if meth.to_s.match(/\A(#{routes.collect { |name,route| name }.join("|")})_(url|path)\Z/)
11
+ ActionDispatch::Routing::RouteSet::NamedRouteCollection::UrlHelper.create(routes.get($1.to_sym), @application.default_url_options).call(Rails.application.routes, args)
12
+ else
13
+ super
14
+ end
15
+ end
16
+
17
+ protected
18
+
19
+ def initialize(app)
20
+ @application = app
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,22 @@
1
+ module Excursion
2
+ module Helpers
3
+ module Helper
4
+
5
+ def method_missing(meth, *args)
6
+ if !(app = Pool.application(meth.to_s)).nil?
7
+ @application_helpers ||= {}
8
+ @application_helpers[app.name] ||= ApplicationHelper.new(app)
9
+ else
10
+ begin
11
+ super
12
+ rescue NoMethodError => e
13
+ raise "Excursion URL helper method does not exist: #{meth}"
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
20
+
21
+ ActionController::Base.send :include, Excursion::Helpers::Helper
22
+ ActionController::Base.send :helper, Excursion::Helpers::Helper
@@ -0,0 +1,7 @@
1
+ require 'excursion/helpers/application_helper'
2
+ require 'excursion/helpers/helper'
3
+
4
+ module Exursion
5
+ module Helpers
6
+ end
7
+ end
@@ -0,0 +1,61 @@
1
+ module Excursion
2
+ module Pool
3
+ class Application
4
+ attr_reader :name, :default_url_options
5
+
6
+ def self.from_cache(cached)
7
+ new.from_cache(cached)
8
+ end
9
+
10
+ def route(key)
11
+ routes[key.to_sym]
12
+ end
13
+
14
+ def routes
15
+ @routes ||= ActionDispatch::Routing::RouteSet::NamedRouteCollection.new
16
+ end
17
+
18
+ def routes=(routes)
19
+ @routes = ActionDispatch::Routing::RouteSet::NamedRouteCollection.new
20
+ routes.each do |name, route|
21
+ @routes.add(name, route)
22
+ end
23
+ end
24
+
25
+ def set_routes(routes)
26
+ self.routes = routes
27
+ self
28
+ end
29
+
30
+ def to_cache
31
+ {name: @name,
32
+ routes: Hash[routes.map { |name, route| [name.to_sym, route.path.spec.to_s] }],
33
+ default_url_options: @default_url_options,
34
+ registered_at: @registered_at
35
+ }
36
+ end
37
+
38
+ def routes_from_cache(routes)
39
+ collection = ActionDispatch::Routing::RouteSet::NamedRouteCollection.new
40
+ routes.each do |name, path|
41
+ collection.add(name, ActionDispatch::Journey::Route.new(name, Rails.application, ActionDispatch::Journey::Path::Pattern.new(path), {required_defaults: []}))
42
+ end
43
+ collection
44
+ end
45
+
46
+ def from_cache(cached={})
47
+ @name = cached[:name] # required
48
+ @routes = routes_from_cache(cached[:routes]) if cached.has_key?(:routes)
49
+ @default_url_options = cached[:default_url_options]
50
+ @registered_at = (Time.at(cached[:registered_at]) rescue Time.now)
51
+ self
52
+ end
53
+
54
+ protected
55
+
56
+ def initialize(config={}, routes={})
57
+ from_cache(config).set_routes(routes)
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,30 @@
1
+ require 'excursion/pool/application'
2
+
3
+ module Excursion
4
+ module Pool
5
+ @@applications = {}
6
+
7
+ def self.application(name)
8
+ return @@applications[name] if @@applications.has_key?(name)
9
+
10
+ app_yaml = datasource.get(name)
11
+ @@applications[name] = Application.from_cache(app_yaml) unless app_yaml.nil?
12
+ end
13
+
14
+ def self.register_application(app)
15
+ name = app.class.name.underscore.split("/").first
16
+ config = {name: name, default_url_options: Excursion.configuration.default_url_options}
17
+
18
+ @@applications[name] = Application.new(config, app.routes.named_routes)
19
+ datasource.set(name, @@applications[name].to_cache)
20
+ end
21
+
22
+ def self.datasource
23
+ raise if Excursion.configuration.datasource.nil?
24
+ require "excursion/datasources/#{Excursion.configuration.datasource.to_s}"
25
+ @@datasource ||= "Excursion::Datasources::#{Excursion.configuration.datasource.to_s.camelize}".constantize.new
26
+ rescue
27
+ raise "Could not initialize your datasource. Make sure you have properly configured it"
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,17 @@
1
+ module Excursion
2
+ class Railtie < Rails::Railtie
3
+ config.after_initialize do |app|
4
+ app.reload_routes!
5
+ Excursion::Pool.register_application(app)
6
+ end
7
+
8
+ rake_tasks do
9
+ namespace :excursion do
10
+ desc "Register this app and it's routes with the route pool"
11
+ task :register => :environment do
12
+ Excursion::Pool.register_application(Rails.application)
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,3 @@
1
+ module Excursion
2
+ VERSION = '0.0.1'
3
+ end
data/lib/excursion.rb ADDED
@@ -0,0 +1,17 @@
1
+ require 'excursion/configuration'
2
+
3
+ module Excursion
4
+ @@configuration = Excursion::Configuration.new
5
+
6
+ def self.configure(&block)
7
+ @@configuration.configure &block
8
+ end
9
+
10
+ def self.configuration
11
+ @@configuration
12
+ end
13
+ end
14
+
15
+ require 'excursion/pool'
16
+ require 'excursion/helpers'
17
+ require 'excursion/railtie'
@@ -0,0 +1 @@
1
+ # TODO: specs!
metadata ADDED
@@ -0,0 +1,87 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: excursion
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Mark Rebec
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-06-13 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rails
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rspec-rails
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ description: Provides a pool of routes into which applications can dump their host
42
+ information and routing table. Other applications can then utilize application namespaced
43
+ helper methods for redirecting, etc. between apps.
44
+ email:
45
+ - mark@markrebec.com
46
+ executables: []
47
+ extensions: []
48
+ extra_rdoc_files: []
49
+ files:
50
+ - lib/excursion/pool.rb
51
+ - lib/excursion/pool/application.rb
52
+ - lib/excursion/railtie.rb
53
+ - lib/excursion/configuration.rb
54
+ - lib/excursion/datasources/file.rb
55
+ - lib/excursion/datasources/datasource.rb
56
+ - lib/excursion/helpers/application_helper.rb
57
+ - lib/excursion/helpers/helper.rb
58
+ - lib/excursion/helpers.rb
59
+ - lib/excursion/version.rb
60
+ - lib/excursion.rb
61
+ - spec/spec_helper.rb
62
+ homepage: http://github.com/markrebec/excursion
63
+ licenses: []
64
+ metadata: {}
65
+ post_install_message:
66
+ rdoc_options: []
67
+ require_paths:
68
+ - lib
69
+ required_ruby_version: !ruby/object:Gem::Requirement
70
+ requirements:
71
+ - - '>='
72
+ - !ruby/object:Gem::Version
73
+ version: '0'
74
+ required_rubygems_version: !ruby/object:Gem::Requirement
75
+ requirements:
76
+ - - '>='
77
+ - !ruby/object:Gem::Version
78
+ version: '0'
79
+ requirements: []
80
+ rubyforge_project:
81
+ rubygems_version: 2.0.0.rc.2
82
+ signing_key:
83
+ specification_version: 4
84
+ summary: Route pooling to share routes between applications
85
+ test_files:
86
+ - spec/spec_helper.rb
87
+ has_rdoc: