cloud_powers 1.0.1 → 1.1.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9cc966e1561d2a202cfa35dd2cf3147d4ef2b840
4
- data.tar.gz: d371b86048fef80382f4bc6cd61a3a4a5a7d16bf
3
+ metadata.gz: 0eca6befe5c9eec2c6467c012fbe341e0152728e
4
+ data.tar.gz: 8e6e169a6ed75c5c3da387d49e4c635f501e72ef
5
5
  SHA512:
6
- metadata.gz: 2125004e0684f341d86a5c04ad62edeafb44ee8de978a7487518d319594e0ac165296170cdb1930a6e1928814198c9dd67729a9d0ba8cb10d8604a072b94c78a
7
- data.tar.gz: 8fc1f114aa0be9caedd619e611d3e3014ac31c3f55113b0ba661a50f1b014e3996c711c8a108601673044c0b4aca22307b2f308fae73679119a724de192c2b0d
6
+ metadata.gz: d1a9e681a605063b21d71c5b449d5a9385caa655e68304e017dca1e05e02ec0ee500358e5415bcd8cdaff9755250d9f8b5e2a541f732b3b1b26907366bca84fd
7
+ data.tar.gz: 2d1fb49aa5756d5163163585977a75ed6d2281d7dc1271615cc8f529e4ac44f85e4343b3d2df43c2373ef0b6b4375c0b45685a1dfb4454309342774f2ade951a
data/.gitignore CHANGED
@@ -10,7 +10,6 @@
10
10
  **/tmp/
11
11
  **/*.env
12
12
  **/.byebug_history
13
- **/lib/cloud_powers/synapse/.DS_Store
14
- **/.DS_Store
15
- **/./**/.DS_Store
13
+ **/.DS_Store*
16
14
  **/*.swp
15
+ **/*zlib
data/.test.env.example CHANGED
@@ -17,6 +17,7 @@ STATUS_STREAM="e.g. kinesis stream name"
17
17
 
18
18
  # Aws s3 buckets etc
19
19
  JOB_STORAGE="e.g. s3 object name"
20
+ JOBS_STORAGE="same as JOB_STORAGE"
20
21
 
21
22
  # Aws sqs queue addresses
22
23
  BACKLOG_QUEUE_ADDRESS=""
data/cloud_powers.gemspec CHANGED
@@ -41,8 +41,8 @@ Gem::Specification.new do |spec|
41
41
  spec.add_runtime_dependency 'httparty', '~> 0.14'
42
42
  spec.add_runtime_dependency 'rubyzip', '~> 1.2'
43
43
  spec.add_runtime_dependency 'zip-zip', '~> 0.3'
44
- spec.add_runtime_dependency 'websocket-eventmachine-server'
45
- spec.add_runtime_dependency 'websocket-eventmachine-client'
44
+ spec.add_runtime_dependency 'websocket-eventmachine-server', '~> 1.0.1'
45
+ spec.add_runtime_dependency 'websocket-eventmachine-client', '~> 1.2.0'
46
46
  spec.add_runtime_dependency 'workflow'
47
47
 
48
48
  spec.add_development_dependency 'bundler', '~> 1.14.3'
@@ -83,8 +83,9 @@ module Smash
83
83
 
84
84
  module AfterHooks
85
85
  # Alternative to <tt>save!()</tt>. This predicate method is based off
86
- # the <tt>@linked</tt> i-var and is set to true after it has been confirmed
87
- # that this resource is a good map to the resource in the cloud.
86
+ # the <tt>@linked</tt> i-var and is set to true after it has been
87
+ # confirmed that this resource is a good map to the resource in the
88
+ # cloud.
88
89
  #
89
90
  # Returns
90
91
  # * +Boolean+
@@ -92,18 +93,24 @@ module Smash
92
93
  !!@linked
93
94
  end
94
95
 
95
- # An +after_hook+ style method that sends a reqeust to your custom implementation
96
- # of the <tt>create_resource</tt> methodallows you to do things after you
97
- # create the resource, in the cloud. This method relies on you having
98
- # a <tt>create_resource</tt> method that can handle every aspect of creating
99
- # your resource. If this piece of the contract isn't obeyed, you will
100
- # receive a <tt>NoMethodError</tt>.
96
+ # An +after_hook+ style method that sends a reqeust to your custom
97
+ # implementation of the <tt>create_resource</tt> methodallows you to do
98
+ # things after you create the resource, in the cloud. This method
99
+ # relies on you having a <tt>create_resource</tt> method that can handle
100
+ # every aspect of creating your resource. If this piece of the contract
101
+ # isn't obeyed, you will receive a <tt>NoMethodError</tt>.
101
102
  #
102
103
  # Returns
103
104
  # +Boolean+ - +true+ if the resource
105
+ #
106
+ # Notes:
107
+ # * This method relies on you implementing a method called
108
+ # +create_resource+ in your class. If you don't, this code will still
109
+ # execute without errors but +@saved+ will remain +false+
104
110
  def save!
105
111
  resp = create_resource if self.respond_to? :create_resource
106
112
  @saved = !resp.nil?
113
+ resp
107
114
  end
108
115
 
109
116
  # Find out if the resource was created
@@ -117,6 +124,3 @@ module Smash
117
124
  end
118
125
  end
119
126
  end
120
-
121
-
122
-
@@ -0,0 +1,88 @@
1
+
2
+
3
+
4
+ 'Hey,'.kind_of? Object &&
5
+ 'you guuyyys!'.is_a? String
6
+ #=> true
7
+
8
+
9
+
10
+
11
+ 1.kind_of? Object &&
12
+ 1.is_a? Numeric
13
+ #=> true
14
+
15
+
16
+
17
+
18
+ person_hash = {
19
+ name: 'Fredward Mc',
20
+ nationality: "'MERCA"
21
+ }
22
+ person_hash.kind_of? Object &&
23
+ person_hash.kind_of? Enumerable
24
+ # => true
25
+
26
+
27
+
28
+
29
+ class Person
30
+ self
31
+ end
32
+
33
+ fredward = Person.new
34
+ fredward.kind_of? Object &&
35
+ fredward.is_a? Person
36
+ #=> true, probably
37
+
38
+
39
+
40
+
41
+ system('compress', 'this.rb', 'and.sh', 'that.js', fredward, -> { some_method })
42
+
43
+
44
+
45
+
46
+
47
+ fredward
48
+
49
+
50
+
51
+ fredward.cats.select do |cat|
52
+ cat.pays_rent?
53
+ end
54
+
55
+
56
+ class Person
57
+ attr_accessor :name
58
+
59
+ def initialize(**opts)
60
+ @name = opts[:name]
61
+ end
62
+
63
+ def speak(words)
64
+ "Hi, I'm #{@name} and #{words}"
65
+ end
66
+ end
67
+
68
+ batman = Person.new(name: 'Bruce')
69
+
70
+
71
+ batman.speak("I'm Batman")
72
+ => "Hi, I'm Bruce and I'm Batman"
73
+
74
+
75
+ class Yokl < Person
76
+ attr_accessor :cats
77
+
78
+ def initialize(**opts)
79
+ super
80
+ @cats = opts[:cats]
81
+ end
82
+
83
+ def speak(words)
84
+ "#{super(words).upcase}, YA'LL"
85
+ end
86
+ end
87
+
88
+ fredward = Yokl.new(name: 'Fredward Mc', cats: ['bud', 'icehouse', 'miller', 'modelo', 'pabst'])
@@ -1,7 +1,6 @@
1
1
  module Smash
2
2
  module CloudPowers
3
3
  module LangHelp
4
-
5
4
  # Allows you to modify all keys, including nested, with a block that you pass.
6
5
  # If no block is passed, a copy is returned.
7
6
  #
@@ -50,6 +49,33 @@ module Smash
50
49
  end
51
50
  end
52
51
 
52
+ # Take an Enumerable apart based on a block. This method works like
53
+ # Array#reject! except it creates 2 new Enumerables of the same type you
54
+ # started with; One has the rejected elements and the other has the kept.
55
+ #
56
+ # Parameters
57
+ # * +Enumerable+ - The Enumerable object to start with
58
+ #
59
+ # Returns
60
+ # * +Enumerable+ - The extracted elements in the same type of Enumerable
61
+ # passed as a parameter
62
+ #
63
+ # Notes:
64
+ # * This modifies the Object passed as a parameter and returns another
65
+ def extract!(enumerable)
66
+ return enumerable if enumerable.nil?
67
+
68
+ if block_given?
69
+ copy = enumerable.dup
70
+
71
+ enumerable.reject! { |k,v| yield k,v }
72
+
73
+ copy.respond_to?(:-) ? (copy - enumerable) : copy.keep_if { |k,v| !enumerable.has_key? k }
74
+ else
75
+ enumerable
76
+ end
77
+ end
78
+
53
79
  # Search through a +Hash+ without knowing if the key is a +String+ or
54
80
  # +Symbol+. A +String+ modification that _normalizes_ each value to compare
55
81
  # is used that is case insensitive. It only leaves word characters, not
@@ -198,13 +224,12 @@ module Smash
198
224
  # Change strings into an i-var format
199
225
  #
200
226
  # Parameters
201
- # * var +String+
227
+ # * key +String+
202
228
  #
203
229
  # Returns
204
230
  # +String+
205
- def to_i_var(var)
206
- var = var.to_s unless var.kind_of? String
207
- /^\W*@\w+/ =~ var ? to_snake(var) : "@#{to_snake(var)}"
231
+ def to_i_var(key)
232
+ "@#{to_snake(key.to_s)}"
208
233
  end
209
234
 
210
235
  # Change strings into PascalCase
@@ -232,7 +257,7 @@ module Smash
232
257
  # * includes ruby file extension
233
258
  # * see #to_snake()
234
259
  def to_ruby_file_name(name)
235
- return name if /\w+\.rb$/ =~ name
260
+ return name if /\w+\.rb$/ =~ name.to_s
236
261
  "#{to_snake(name)}.rb"
237
262
  end
238
263
 
@@ -249,9 +274,8 @@ module Smash
249
274
  # * will not have file extensions
250
275
  # * see #to_ruby_file_name()
251
276
  def to_snake(var)
252
- var = var.to_s unless var.kind_of? String
253
-
254
- var.gsub(/:{2}|\//, '_').
277
+ var.to_s.gsub(/^\W*([A-Z|a-z]*)/,'\1').
278
+ gsub(/:{2}|\//, '_').
255
279
  gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
256
280
  gsub(/([a-z\d])([A-Z])/,'\1_\2').
257
281
  gsub(/\s+/, '_').
@@ -23,16 +23,15 @@ module Smash
23
23
  #
24
24
  # puts @bar
25
25
  # # => 'bar:1475434059'
26
- def attr_map(attributes)
26
+ def attr_map(attributes = self.i_vars)
27
27
  attributes = [attributes, nil] unless attributes.respond_to? :map
28
28
 
29
29
  attributes.inject(self) do |this, (attribute, before_value)|
30
- first_place, second_place = yield attribute, before_value if block_given?
31
-
32
- results = if second_place.nil?
33
- [attribute, first_place]
30
+ results = if block_given?
31
+ first_place, second_place = yield attribute, before_value
32
+ second_place.nil? ? [attribute, first_place] : [first_place, second_place]
34
33
  else
35
- [first_place, second_place]
34
+ [attribute, before_value]
36
35
  end
37
36
 
38
37
  this.instance_variable_set(to_i_var(results.first), results.last)
@@ -45,12 +44,31 @@ module Smash
45
44
  # project root is etc.
46
45
  #
47
46
  # Returns
48
- # +String+
47
+ # * +Pathname+
49
48
  #
50
49
  # Notes
51
- # * Uses +$0+ to figure out what the current file is
50
+ # * Uses <tt>::#caller()</tt> to figure out where the request came from
52
51
  def called_from
53
- File.expand_path(File.dirname($0))
52
+ sanitized_path_string = caller.first.gsub(/:.*/,'')
53
+ calling_file = File.expand_path(sanitized_path_string)
54
+ to_realpath(calling_file).parent
55
+ end
56
+
57
+ # Gather up this object's instance variables and create a +Hash+ from the
58
+ # name/value pairs
59
+ #
60
+ # Returns
61
+ # * +Hash+
62
+ #
63
+ # Example
64
+ # 5class A; attr_accessor :eh; end
65
+ # a.i_var_hash
66
+ # => { eh: nil }
67
+ def i_var_hash
68
+ self.instance_variables.inject({}) do |hash, (k,v)|
69
+ hash[k.to_s.gsub('@', '')] = self.instance_variable_get to_i_var(k)
70
+ hash
71
+ end
54
72
  end
55
73
 
56
74
  # Create an <tt>attr_accessor</tt> feeling getter and setter for an instance
@@ -138,6 +156,7 @@ module Smash
138
156
  opts = {}
139
157
  opts[:extraInfo] = { message: update }
140
158
  end
159
+
141
160
  updated_extra_info = opts.delete(:extraInfo) || {}
142
161
 
143
162
  {
@@ -6,45 +6,52 @@ module Smash
6
6
  module CloudPowers
7
7
  module PathHelp
8
8
 
9
- # Gives a common home for jobs to live so they can be easily grouped and
10
- # found. This method will create nested directories, based on the
11
- # <tt>#project_root()</tt> method and an additional 'lib/jobs' directory.
12
- # If no project root has been set by the time this method is called, a new
13
- # directory will be created relative to the gem's project root.
9
+ # Offer a common "path" delimiter. This is designed to allow Storage keep
10
+ # a common delimiter. It's not required but it makes things a little more
11
+ # human friendly
14
12
  #
15
13
  # Returns
16
14
  # +String+
17
- #
18
- # Notes
19
- # * # If no project root has been set by the time this method is called, a new
20
- # directory will be created relative to the gem's project root. This might
21
- # have deeper implications than you want to deal with so it's always a good
22
- # idea to set your project root as soon as you can.
23
- # * TODO: find a way to have this method figure out the actual project's
24
- # root, as opposed to just making common <i>"good"</i> assumptions.
25
- def job_home
26
- string_th = FileUtils.mkdir_p("#{project_root}/lib/jobs/").first
27
- @job_home ||= Pathname.new(string_th).realpath.to_s
15
+ def common_delimiter
16
+ '/'.freeze
28
17
  end
29
18
 
30
- # Gives the path from the project root to lib/jobs[/#{file}.rb]
19
+ # Expand a +Pathname variable
31
20
  #
32
21
  # Parameters
33
- # * file +String+ (optional) (default is '') - name of a file
22
+ # * arg +String+
34
23
  #
35
24
  # Returns
36
- # * path/file +String+ if +file+ parameter is given. return has
37
- # '.rb' extension included
38
- # * file +String+ if +file+ parameter is not given it will return the
39
- # <tt>#job_require_path()</tt>
25
+ # * +Pathname+ - Absolute path
40
26
  #
41
- # Notes
42
- # * See <tt>#job_home</tt>
43
- def job_path(file = '')
44
- return job_home if file.empty?
45
- Pathname.new("#{job_home}/#{file}").to_s
27
+ # Notes:
28
+ # * This method doesn't guarantee that the path actually exists; It just
29
+ # gives you a correct, absolute path
30
+ def expand_path(arg)
31
+ to_pathname(arg).expand_path
46
32
  end
47
33
 
34
+ # Check if the URL exists
35
+ #
36
+ # Parameters
37
+ # * file +String+
38
+ #
39
+ # Returns
40
+ # +Boolean+
41
+ def file_exists?(*args)
42
+ File.exist?(*args.join('/').to_s)
43
+ end
44
+
45
+ # Determine if this path or name seems like a file or a directory
46
+ #
47
+ # Parameters
48
+ # * +Pathname+|+String+
49
+ #
50
+ # Returns
51
+ # * +Boolean+
52
+ def filename?(pathname)
53
+ !!(/[A-Za-z]*\.[A-Za-z]+$/ =~ pathname.to_s)
54
+ end
48
55
 
49
56
  # Check if the job file exists in the job directory
50
57
  #
@@ -55,14 +62,28 @@ module Smash
55
62
  # +Boolean+
56
63
  #
57
64
  # Notes
58
- # * See +#job_home()+
65
+ # * See <tt>#job_home()</tt>
66
+ # * See <tt>#path_exists?()</tt>
59
67
  def job_exist?(file)
60
- begin
61
- File.new("#{job_home}/#{file}")
62
- true
63
- rescue Errno::ENOENT
64
- false
65
- end
68
+ file_exists?(job_home, file)
69
+ end
70
+
71
+ # Gives the path from the project root to lib/jobs[/#{file}.rb]
72
+ #
73
+ # Parameters
74
+ # * file +String+ (optional) (default is '') - name of a file
75
+ #
76
+ # Returns
77
+ # * path/file +String+ if +file+ parameter is given. return has
78
+ # '.rb' extension included
79
+ # * file +String+ if +file+ parameter is not given it will return the
80
+ # <tt>#job_require_path()</tt>
81
+ #
82
+ # Notes
83
+ # * See <tt>#job_home</tt>
84
+ def job_path(file = '')
85
+ return job_home if file.empty?
86
+ to_pathname(job_home, file)
66
87
  end
67
88
 
68
89
  # Gives the path from the project root to lib/jobs[/file]
@@ -78,6 +99,7 @@ module Smash
78
99
  # * Neither path nor file will have a file extension
79
100
  # * See <tt>#job_home</tt>
80
101
  def job_require_path(file_name = '')
102
+ # TODO: refactor to use Pathname as much as possible
81
103
  begin
82
104
  file_sans_extension = File.basename(file_name, '.*')
83
105
  (Pathname.new(job_home) + file_sans_extension).to_s
@@ -85,6 +107,194 @@ module Smash
85
107
  nil
86
108
  end
87
109
  end
110
+
111
+ # Find all <i>directories</i> that match the given string.
112
+ #
113
+ # Returns
114
+ # * +Pathname+ - absolute path
115
+ #
116
+ # Notes
117
+ # * This method is su-looooOOOOOOOw but it's pretty thorough. Fixing that
118
+ # while keeping it thorough is a high priority but it works. Your best
119
+ # bet is to try to set the location for things you're looking for, before
120
+ # you use them. Another alternative is to use a jailed root to run your
121
+ # project from.
122
+ def file_search(name, scope = '/**')
123
+ Pathname.glob("#{scope}/#{name}").select(&:exist?).reject(&:directory?).map(&:realpath)
124
+ end
125
+
126
+
127
+ def paths_lcd(*paths)
128
+ unpacked_paths = paths.map { |path| path.to_s.split('/') }.sort
129
+ shortest_path_dirs = unpacked_paths.first.count # this is the shortest path
130
+ common_path = []
131
+
132
+ (0..shortest_path_dirs).each do |i|
133
+ if unpacked_paths.first[i] == unpacked_paths.last[i]
134
+ common_path << unpacked_paths.first[i]
135
+ end
136
+ end
137
+
138
+ to_pathname(common_path.join('/'))
139
+ end
140
+
141
+ def paths_gcd(*paths)
142
+ start_from = paths_lcd(*paths)
143
+ paths.sort.last.relative_path_from(start_from)
144
+ end
145
+
146
+ # Find all <i>directories</i> that match the given string.
147
+ #
148
+ # Returns
149
+ # * +Pathname+ - absolute path
150
+ #
151
+ # Notes
152
+ # * This method is su-looooOOOOOOOw but it's pretty thorough. Fixing that
153
+ # while keeping it thorough is a high priority but it works. Your best
154
+ # bet is to try to set the location for things you're looking for, before
155
+ # you use them. Another alternative is to use a jailed root to run your
156
+ # project from.
157
+ def path_search(name, scope = default_scope)
158
+ Pathname.glob("#{scope}/#{name}").select(&:exist?).select(&:directory?).map(&:realpath)
159
+ end
160
+
161
+ # Convert a list of arguments to a path-like +String+ object.
162
+ #
163
+ # Parameters
164
+ # * [+Object+[,...]]
165
+ #
166
+ # Returns
167
+ # * +String+
168
+ def to_path(*args)
169
+ to_pathname(*args).to_s
170
+ end
171
+
172
+ # Convert a list of arguments to a +Pathname+ object.
173
+ #
174
+ # Parameters
175
+ # * [+String+[,...]]
176
+ #
177
+ # Returns
178
+ # * +Pathname+
179
+ def to_pathname(*args)
180
+ args = args.flatten.compact
181
+ # #join() will create a path that looks like this `//your/path` if the
182
+ # first argument is the same as the path seperator on your system.
183
+ first = /^\/+\W*$/ =~ args.first.to_s ? args.shift : ''
184
+ path_string = args.join('/')
185
+ path_string = first + path_string
186
+ Pathname.new(path_string)
187
+ end
188
+
189
+ # Create and/or get the full path to the argument(s)
190
+ #
191
+ # Parameters
192
+ # * +String+(s) - a path or chunks of a path, in order, as +String+s
193
+ #
194
+ # Returns
195
+ # * +Pathname+
196
+ #
197
+ # Notes:
198
+ # * !This method creates paths, even nested paths, if they don't exist!
199
+ # * !Use <tt>expand_path</tt> if you don't want to create anything but still
200
+ # need the full path
201
+ # * See <tt>#to_pathname</tt>
202
+ # * See <tt>#touch</tt>
203
+ def to_realpath(*args)
204
+ begin
205
+ pathname = to_pathname(*args)
206
+ pathname.realpath
207
+ rescue Errno::ENOENT => e
208
+ logger.debug("#to_realpath(#{pathname}) called from " +
209
+ "#{caller.first} but the path doesn't exist")
210
+ to_realpath(touch(pathname))
211
+ end
212
+ end
213
+
214
+ # Create a file or directory. You don't have to worry if the path exists.
215
+ #
216
+ # Parameters
217
+ # * path +Pathname+|+String+ - path that you would like created
218
+ #
219
+ # Returns
220
+ # * +Pathname+ - path to your new object
221
+ #
222
+ # Notes:
223
+ # * This method assumes you are careful enough not to break your machine
224
+ # because you might accidentally over-write an existing, important path
225
+ # with an empty file or directory. That's no different than any other
226
+ # library, like +FileUtils+ or +Pathname+ but it's worht being said,
227
+ # just for good measure.
228
+ def touch(path)
229
+ pathname = to_pathname(path)
230
+ filename?(pathname) ? ::FileUtils.touch(pathname) : ::FileUtils.mkdir_p(pathname)
231
+ to_realpath(pathname)
232
+ end
233
+
234
+ # Offer a common place to operate from, so <tt>CloudPowers</tt> stays tidy.
235
+ # This method will find out if your project responds to a method called
236
+ # 'project_root'. If the method exist, it uses it, otherwise, your new
237
+ # files etc. will be places at <tt>`pwd`/zlib</tt>.
238
+ #
239
+ # Returns
240
+ # * +Pathname+
241
+ #
242
+ # Notes:
243
+ # * See <tt>to_realpath</tt>
244
+ def zlib_path(object = '')
245
+ return zlib_home if (object.nil? || object.empty?)
246
+ to_path(zlib_home, object)
247
+ end
248
+
249
+ private
250
+ def has_project_root_defined?
251
+ self.respond_to? :project_root
252
+ end
253
+
254
+ # Gives a common home for jobs to live so they can be easily grouped and
255
+ # found. This method will create nested directories, based on the
256
+ # <tt>#project_root()</tt> method and an additional 'lib/jobs' directory.
257
+ # If no project root has been set by the time this method is called, a new
258
+ # directory will be created relative to the gem's project root.
259
+ #
260
+ # Returns
261
+ # +Pathname+
262
+ def job_home
263
+ path_string = "#{zlib_path}/jobs"
264
+ @job_home ||= path_search(path_string).first || to_realpath(path_string)
265
+ end
266
+
267
+ # Gives a common home for this project to store or read from. This method
268
+ # will create nested directories, based on the <tt>#project_root</tt>
269
+ # method if it exists, or it will create the +zlib+ directory wherever this
270
+ # method was called from.
271
+ #
272
+ # Returns
273
+ # * +Pathname+
274
+ #
275
+ # Notes
276
+ # * # If no project root has been set by the time this method is called, a new
277
+ # directory will be created relative to the gem's project root. This might
278
+ # have deeper implications than you want to deal with so it's always a good
279
+ # idea to set your project root as soon as you can.
280
+ # * TODO: find a way to have this method figure out the actual project's
281
+ # root, as opposed to just making common <i>"good"</i> assumptions.
282
+ def zlib_home
283
+ @zlib_home ||= to_realpath(
284
+ has_project_root_defined? ? project_root + 'zlib' : './zlib'
285
+ )
286
+ end
287
+
288
+ private
289
+ def default_scope
290
+ if self.respond_to? :origin
291
+ origin
292
+ elsif self.respond_to? :project_root
293
+ project_root || proc_cwd || ps_cwd
294
+ else
295
+ to_realpath(called_from).parent
296
+ end
297
+ end
88
298
  end
89
299
  end
90
300
  end
@@ -19,9 +19,11 @@ module Smash
19
19
  attr_accessor :name
20
20
  # whether or not a call has been made to the cloud to back this resource
21
21
  attr_accessor :linked
22
+ # metadata, i.e. tracking on the remote resource that maps to this resource
23
+ attr_accessor :meta
22
24
  # the ID in the cloud; e.g. ARN for AWS, etc
23
25
  attr_accessor :remote_id
24
- # tracking on the remote resource that maps to this resource
26
+ # @tags will be deprecated in V2. Please use @meta
25
27
  attr_accessor :tags
26
28
  # the type of resource this was instantiated as
27
29
  attr_accessor :type
@@ -30,14 +32,16 @@ module Smash
30
32
  # inherits from this class. The initialize method follows the method
31
33
  # signature for the active record-like pattern being followed throughout
32
34
  # the code
33
- def initialize(name:, client: nil, **config)
35
+ def initialize(name:, **config)
34
36
  @linked = false
35
37
  @saved = false
36
- @client = client
37
- @type = to_snake(self.class.name.split('::').last)
38
+ @client = config[:client]
39
+ @type = to_snake(config[:named_type] || config[:type] || self.class.name.split('::').last)
38
40
  @call_name = to_snake("#{name}_#{@type}")
39
41
  @name = name
40
- @tags = Array.new
42
+ @meta = Array.new # TODO: create a Meta resource and use it here
43
+ @tags = @meta
44
+ logger.debug '@tags will be deprecated in V2. Please use @meta'
41
45
  end
42
46
  end
43
47
  end