ruroku 0.0.1 → 0.0.2

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.
Files changed (57) hide show
  1. data/.travis.yml +5 -0
  2. data/CHANGELOG.md +12 -0
  3. data/Gemfile +9 -0
  4. data/README.md +180 -48
  5. data/Rakefile +7 -1
  6. data/TODO.md +0 -4
  7. data/lib/ruroku.rb +9 -1
  8. data/lib/ruroku/addon.rb +8 -10
  9. data/lib/ruroku/addon_set.rb +4 -1
  10. data/lib/ruroku/api.rb +20 -1
  11. data/lib/ruroku/app.rb +29 -20
  12. data/lib/ruroku/app_set.rb +13 -0
  13. data/lib/ruroku/base.rb +20 -3
  14. data/lib/ruroku/collaborator.rb +5 -2
  15. data/lib/ruroku/collaborator_set.rb +4 -1
  16. data/lib/ruroku/config_var.rb +9 -2
  17. data/lib/ruroku/config_var_set.rb +5 -2
  18. data/lib/ruroku/domain.rb +8 -9
  19. data/lib/ruroku/domain_set.rb +4 -1
  20. data/lib/ruroku/key.rb +8 -0
  21. data/lib/ruroku/key_set.rb +17 -0
  22. data/lib/ruroku/nested_base.rb +3 -2
  23. data/lib/ruroku/nested_resource_set.rb +28 -0
  24. data/lib/ruroku/process.rb +14 -11
  25. data/lib/ruroku/process_set.rb +11 -28
  26. data/lib/ruroku/release.rb +9 -5
  27. data/lib/ruroku/release_set.rb +4 -1
  28. data/lib/ruroku/resource_set.rb +61 -6
  29. data/lib/ruroku/stack.rb +10 -0
  30. data/lib/ruroku/stack_set.rb +13 -0
  31. data/lib/ruroku/user.rb +15 -0
  32. data/lib/ruroku/version.rb +1 -1
  33. data/ruroku.gemspec +4 -5
  34. data/spec/helpers/addon.rb +12 -0
  35. data/spec/helpers/app.rb +18 -0
  36. data/spec/helpers/collaborator.rb +11 -0
  37. data/spec/helpers/config_var.rb +11 -0
  38. data/spec/helpers/domain.rb +13 -0
  39. data/spec/helpers/keys.rb +12 -0
  40. data/spec/helpers/process.rb +15 -0
  41. data/spec/helpers/release.rb +15 -0
  42. data/spec/helpers/stack.rb +11 -0
  43. data/spec/helpers/user.rb +15 -0
  44. data/spec/ruroku/addon_set_spec.rb +29 -0
  45. data/spec/ruroku/api_spec.rb +55 -0
  46. data/spec/ruroku/app_set_spec.rb +15 -0
  47. data/spec/ruroku/app_spec.rb +113 -0
  48. data/spec/ruroku/collaborator_set_spec.rb +22 -0
  49. data/spec/ruroku/domain_set_spec.rb +22 -0
  50. data/spec/ruroku/key_set_spec.rb +29 -0
  51. data/spec/ruroku/nested_resource_set_spec.rb +27 -0
  52. data/spec/ruroku/process_set_spec.rb +36 -0
  53. data/spec/ruroku/release_set_spec.rb +15 -0
  54. data/spec/ruroku/resource_set_spec.rb +26 -0
  55. data/spec/ruroku/stack_set_spec.rb +15 -0
  56. data/spec/spec_helper.rb +72 -0
  57. metadata +70 -15
data/lib/ruroku/app.rb CHANGED
@@ -1,32 +1,53 @@
1
1
  module Ruroku
2
2
  class App < Base
3
- attr_accessor :id, :name, :create_status, :created_at, :stack, :git_url,
4
- :requested_stack, :repo_migrate_status, :slug_size, :repo_size,
5
- :dynos, :workers
3
+ attribute :id, Integer
4
+ attribute :name, String
5
+ attribute :create_status, String
6
+ attribute :stack, String
7
+ attribute :requested_stack, String
8
+ attribute :git_url, String
9
+ attribute :repo_migrate_status, String
10
+ attribute :slug_size, Integer
11
+ attribute :repo_size, Integer
12
+ attribute :dynos, Integer
13
+ attribute :workers, Integer
14
+ attribute :created_at, Time
15
+
16
+ resource_id :name
6
17
 
7
18
  # Public: Get addons associated with current app.
8
19
  def addons
9
- AddonSet.new self, *api.get_addons(name).body.map { |addon| Addon.new self, addon }
20
+ @addons ||= AddonSet.new self
10
21
  end
11
22
 
12
23
  # Public: Get collaborators associated with current app.
13
24
  def collaborators
14
- CollaboratorSet.new self, *api.get_collaborators(name).body.map { |collaborator| Collaborator.new self, collaborator }
25
+ @collaborators ||= CollaboratorSet.new self
15
26
  end
16
27
 
17
28
  # Public: Get config vars associated with current app.
18
29
  def config_vars
19
- ConfigVarSet.new self, *api.get_config_vars(name).body.map { |key, value| ConfigVar.new self, key: key, value: value }
30
+ @config_vars ||= ConfigVarSet.new self
31
+ end
32
+
33
+ # Public: Get domains associated with current app.
34
+ def domains
35
+ @domains ||= DomainSet.new self
20
36
  end
21
37
 
22
38
  # Public: Get processes associated with current app.
23
39
  def processes
24
- ProcessSet.new self, *api.get_ps(name).body.map { |ps| Process.new self, ps }
40
+ @processes ||= ProcessSet.new self
25
41
  end
26
42
 
27
43
  # Public: Get releases associated with current app.
28
44
  def releases
29
- ReleaseSet.new self, *api.get_releases(name).body.map { |release| Release.new self, release }
45
+ @releases ||= ReleaseSet.new self
46
+ end
47
+
48
+ # Public: Get available stacks for current app.
49
+ def stacks
50
+ @stacks ||= StackSet.new self
30
51
  end
31
52
 
32
53
  # Public: Turn the maintenance mode on.
@@ -38,17 +59,5 @@ module Ruroku
38
59
  def no_maintenance!
39
60
  api.post_app_maintenance name, '0'
40
61
  end
41
-
42
- def created_at=(value)
43
- @created_at = Time.parse value
44
- end
45
-
46
- def slug_size=(value)
47
- @slug_size = value.to_i.bytes
48
- end
49
-
50
- def repo_size=(value)
51
- @repo_size = value.to_i.bytes
52
- end
53
62
  end
54
63
  end
@@ -0,0 +1,13 @@
1
+ module Ruroku
2
+ class AppSet < ResourceSet
3
+ resource_class App
4
+ collection_api_selector :get_apps
5
+
6
+ # Map API methods to collection methods.
7
+ #
8
+ # Examples
9
+ #
10
+ # apps.create 'another-app', 'cedar'
11
+ map_api create: :post_app
12
+ end
13
+ end
data/lib/ruroku/base.rb CHANGED
@@ -1,13 +1,30 @@
1
1
  module Ruroku
2
2
  class Base
3
+ include Virtus
4
+
3
5
  attr_accessor :api
4
6
 
5
7
  def initialize(api, attributes = {})
6
8
  self.api = api
7
9
 
8
- attributes.each do |key, value|
9
- method = "#{key}="
10
- send method, value if respond_to? method
10
+ super attributes
11
+ end
12
+
13
+ # Public: Define resource id key.
14
+ def self.resource_id(id_key = nil)
15
+ if id_key
16
+ @_resource_id = id_key
17
+ else
18
+ @_resource_id
19
+ end
20
+ end
21
+
22
+ def inspect
23
+ if self.class.resource_id
24
+ resource_id = send self.class.resource_id
25
+ "<#{self.class} #{resource_id}>"
26
+ else
27
+ "<#{self.class}>"
11
28
  end
12
29
  end
13
30
  end
@@ -1,6 +1,9 @@
1
1
  module Ruroku
2
2
  class Collaborator < NestedBase
3
- attr_accessor :email, :access
4
- deletable :email
3
+ attribute :email, String
4
+ attribute :access, String
5
+
6
+ resource_id :email
7
+ deletable_resource
5
8
  end
6
9
  end
@@ -1,5 +1,8 @@
1
1
  module Ruroku
2
- class CollaboratorSet < ResourceSet
2
+ class CollaboratorSet < NestedResourceSet
3
+ resource_class Collaborator
4
+ collection_api_selector :get_collaborators
5
+
3
6
  # Map API methods to collection methods.
4
7
  #
5
8
  # Examples
@@ -1,7 +1,10 @@
1
1
  module Ruroku
2
2
  class ConfigVar < NestedBase
3
- attr_accessor :key, :value
4
- deletable :key
3
+ attribute :key, String
4
+ attribute :value, String
5
+
6
+ resource_id :key
7
+ deletable_resource
5
8
 
6
9
  def value=(new_value)
7
10
  if @value.nil?
@@ -11,5 +14,9 @@ module Ruroku
11
14
  @value = new_value
12
15
  end
13
16
  end
17
+
18
+ def inspect
19
+ "<#{self.class} #{key} => #{value}>"
20
+ end
14
21
  end
15
22
  end
@@ -1,11 +1,14 @@
1
1
  module Ruroku
2
- class ConfigVarSet < ResourceSet
2
+ class ConfigVarSet < NestedResourceSet
3
+ resource_class ConfigVar
4
+ collection_api_selector :get_config_vars
5
+
3
6
  # Map API methods to collection methods.
4
7
  #
5
8
  # Examples
6
9
  #
7
10
  # config_vars.add 'KEY' => 'value'
8
- # config_vars.delete 'KEY' => 'value'
11
+ # config_vars.delete 'KEY'
9
12
  map_api add: :post_config_vars,
10
13
  delete: :delete_config_var
11
14
  end
data/lib/ruroku/domain.rb CHANGED
@@ -1,14 +1,13 @@
1
1
  module Ruroku
2
2
  class Domain < NestedBase
3
- attr_accessor :id, :domain, :base_domain, :default, :created_at, :updated_at
4
- deletable :domain
3
+ attribute :id, Integer
4
+ attribute :domain, String
5
+ attribute :base_domain, String
6
+ attribute :default, Boolean, default: false
7
+ attribute :created_at, Time
8
+ attribute :updated_at, Time
5
9
 
6
- def created_at=(value)
7
- @created_at = Time.parse value
8
- end
9
-
10
- def updated_at=(value)
11
- @updated_at = Time.parse value
12
- end
10
+ resource_id :domain
11
+ deletable_resource
13
12
  end
14
13
  end
@@ -1,5 +1,8 @@
1
1
  module Ruroku
2
- class DomainSet < ResourceSet
2
+ class DomainSet < NestedResourceSet
3
+ resource_class Domain
4
+ collection_api_selector :get_domains
5
+
3
6
  # Map API methods to collection methods.
4
7
  #
5
8
  # Examples
data/lib/ruroku/key.rb ADDED
@@ -0,0 +1,8 @@
1
+ module Ruroku
2
+ class Key < Base
3
+ attribute :email, String
4
+ attribute :contents, String
5
+
6
+ resource_id :email
7
+ end
8
+ end
@@ -0,0 +1,17 @@
1
+ module Ruroku
2
+ class KeySet < ResourceSet
3
+ resource_class Key
4
+ collection_api_selector :get_keys
5
+
6
+ # Map API methods to collection methods.
7
+ #
8
+ # Examples
9
+ #
10
+ # keys.add 'id rsa pub content here'
11
+ # keys.delete 'email@me.com'
12
+ # keys.delete_all
13
+ map_api add: :post_key,
14
+ delete: :delete_key,
15
+ delete_all: :delete_keys
16
+ end
17
+ end
@@ -8,12 +8,13 @@ module Ruroku
8
8
  super app.api, attributes
9
9
  end
10
10
 
11
- def self.deletable(resource_id)
11
+ # Public: Make resource deletable.
12
+ def self.deletable_resource
12
13
  resource_name = name.demodulize.underscore
13
14
 
14
15
  define_method :delete! do
15
16
  api_method = "delete_#{resource_name}"
16
- resource_id = send resource_id
17
+ resource_id = send self.class.resource_id
17
18
  api.send api_method, app.name, resource_id
18
19
  end
19
20
  end
@@ -0,0 +1,28 @@
1
+ module Ruroku
2
+ class NestedResourceSet < ResourceSet
3
+ attr_accessor :app
4
+
5
+ def initialize(app, *args)
6
+ self.app = app
7
+
8
+ super app.api, *args
9
+ end
10
+
11
+ def build_resource(response)
12
+ resource_class = self.class.resource_class
13
+ resource_class.new app, response
14
+ end
15
+
16
+ def collection_query_params
17
+ [app.name]
18
+ end
19
+
20
+ def self.map_api(methods)
21
+ methods.each do |method_name, api_mapping|
22
+ define_method method_name do |*args|
23
+ api.send api_mapping, app.name, *args
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -1,7 +1,19 @@
1
1
  module Ruroku
2
2
  class Process < NestedBase
3
- attr_accessor :process, :type, :command, :upid, :slug, :action,
4
- :pretty_state, :elapsed, :rendezvous_url, :attached, :transitioned_at
3
+ attribute :process, String
4
+ attribute :type, String
5
+ attribute :command, String
6
+ attribute :upid, String
7
+ attribute :slug, String
8
+ attribute :action, String
9
+ attribute :state, String
10
+ attribute :pretty_state, String
11
+ attribute :elapsed, Integer
12
+ attribute :rendezvous_url, String
13
+ attribute :attached, Boolean, default: false
14
+ attribute :transitioned_at, Time
15
+
16
+ resource_id :process
5
17
 
6
18
  # Public: Restart the process.
7
19
  def restart
@@ -12,14 +24,5 @@ module Ruroku
12
24
  def stop
13
25
  api.post_ps_stop app.name, 'ps' => process
14
26
  end
15
-
16
- # Public: Check if the process is attached.
17
- def attached?
18
- !!attached
19
- end
20
-
21
- def transitioned_at=(value)
22
- @transitioned_at = Time.parse value
23
- end
24
27
  end
25
28
  end
@@ -1,37 +1,20 @@
1
1
  module Ruroku
2
- class ProcessSet < ResourceSet
3
- # Publc: Run the command.
4
- #
5
- # command - The String command.
6
- def run(command)
7
- api.post_ps app.name, command
8
- end
9
-
10
- # Public: Restart all the processes.
11
- def restart
12
- api.post_ps_restart app.name
13
- end
14
-
15
- # Public: Scale processes.
16
- #
17
- # type - The String process type.
18
- # qty - The Integer process quantity.
19
- def scale(type, qty)
20
- api.ps_scale app.name, type, qty
21
- end
2
+ class ProcessSet < NestedResourceSet
3
+ resource_class Process
4
+ collection_api_selector :get_ps
22
5
 
23
- # Public: Stop the process(es).
6
+ # Map API methods to collection methods.
24
7
  #
25
- # options - The Hash
26
- # either :ps - The String process name
27
- # or :type - The String process type
28
- #
29
8
  # Examples
30
9
  #
10
+ # processes.run 'rake task'
11
+ # processes.restart
12
+ # processes.scale 'web', 10
31
13
  # processes.stop 'ps' => 'web.1'
32
14
  # processes.stop 'type' => 'web'
33
- def stop(options)
34
- api.post_ps_stop app.name, options
35
- end
15
+ map_api run: :post_ps,
16
+ restart: :post_ps_restart,
17
+ scale: :ps_scale,
18
+ stop: :post_ps_stop
36
19
  end
37
20
  end
@@ -1,10 +1,14 @@
1
1
  module Ruroku
2
2
  class Release < NestedBase
3
- attr_accessor :name, :descr, :user, :commit, :env, :addons, :pstable,
4
- :created_at
3
+ attribute :name, String
4
+ attribute :descr, String
5
+ attribute :user, String
6
+ attribute :commit, String
7
+ attribute :env, Hash
8
+ attribute :addons, Array
9
+ attribute :pstable, Hash
10
+ attribute :created_at, Time
5
11
 
6
- def created_at=(value)
7
- @created_at = Time.parse value
8
- end
12
+ resource_id :name
9
13
  end
10
14
  end
@@ -1,5 +1,8 @@
1
1
  module Ruroku
2
- class ReleaseSet < ResourceSet
2
+ class ReleaseSet < NestedResourceSet
3
+ resource_class Release
4
+ collection_api_selector :get_releases
5
+
3
6
  # Map API methods to collection methods.
4
7
  #
5
8
  # Examples
@@ -1,18 +1,73 @@
1
1
  module Ruroku
2
2
  class ResourceSet < Array
3
- attr_accessor :app, :api
3
+ attr_accessor :api
4
4
 
5
- def initialize(app, *args)
6
- self.app = app
7
- self.api = app.api
5
+ def initialize(api, *args)
6
+ self.api = api
8
7
 
9
8
  super args
9
+
10
+ query_collection_objects
11
+ end
12
+
13
+ # Public: Reload collection.
14
+ #
15
+ # Examples
16
+ #
17
+ # collection.reload
18
+ def reload
19
+ clear
20
+ query_collection_objects
21
+ end
22
+
23
+ # Public: Query collection objects from API.
24
+ def query_collection_objects
25
+ collection_objects = api.send(self.class.collection_api_selector, *collection_query_params).body
26
+
27
+ if collection_objects.instance_of? Array
28
+ collection_objects.each do |response|
29
+ self << build_resource(response)
30
+ end
31
+ elsif collection_objects.instance_of? Hash
32
+ collection_objects.each do |key, value|
33
+ self << build_resource(key: key, value: value)
34
+ end
35
+ end
36
+ end
37
+
38
+ # Public: Build a resource from response.
39
+ def build_resource(response)
40
+ resource_class = self.class.resource_class
41
+ resource_class.new response
42
+ end
43
+
44
+ # Public: Get params for querying collection.
45
+ def collection_query_params
46
+ []
47
+ end
48
+
49
+ # Public: Set or get a collection API selector.
50
+ def self.collection_api_selector(meth = nil)
51
+ if meth
52
+ @_collection_api_selector = meth
53
+ else
54
+ @_collection_api_selector
55
+ end
56
+ end
57
+
58
+ # Public: Set or get a collection resource class.
59
+ def self.resource_class(klass = nil)
60
+ if klass
61
+ @_resource_class = klass
62
+ else
63
+ @_resource_class
64
+ end
10
65
  end
11
66
 
12
67
  def self.map_api(methods)
13
68
  methods.each do |method_name, api_mapping|
14
- define_method method_name do |resource_name|
15
- api.send api_mapping, app.name, resource_name
69
+ define_method method_name do |*args|
70
+ api.send api_mapping, *args
16
71
  end
17
72
  end
18
73
  end