shopifydev 0.0.2 → 0.0.3

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.
data/NEXTSTEPS.md CHANGED
@@ -1,26 +1,45 @@
1
1
  # switch command
2
2
 
3
- should be some shortcuts
3
+ Z(2013.06.06):
4
+ M, I think you should work on memoizing the shop array and the 'refresh'
5
+ command. That lag is killing me.
4
6
 
5
- switch cronin
7
+ You should take a look at switch.handle_choices and switch.handle_by_shop_type
8
+ I realized that the object we are calling @cfg is either:
9
+ a string, in which case we should keep going
10
+ a result object, in which case we should switch shops
6
11
 
7
- should look for shops in an app
12
+ So, in handle_choice we determine whether we present a new menu, or go
13
+ ahead and update the current shop
8
14
 
9
- switch with no arguments
10
- you get a list:
15
+ The result object gets a key "shop_type" that lets us know how to deal
16
+ with it. The behaviour for test_shop is already there, but if you could
17
+ implement the behaviour for local, I would be happy
11
18
 
12
- test shops:
13
- 1. cronin
19
+ I wrote a bunch of comments around the commands.rb file, too, so feel free
20
+ to read those
14
21
 
15
- apps (development):
16
- 1. metafieldseditor
17
- 2. shipping
22
+ M: should be some shortcuts
18
23
 
19
- apps (heroku):
20
- 1. metafieldseditor
21
- 2. shipping
24
+ switch cronin
22
25
 
23
- _pry_.switch
26
+ should look for shops in an app
27
+
28
+ switch with no arguments
29
+ you get a list:
30
+
31
+ test shops:
32
+ 1. cronin
33
+
34
+ apps (development):
35
+ 1. metafieldseditor
36
+ 2. shipping
37
+
38
+ apps (heroku):
39
+ 1. metafieldseditor
40
+ 2. shipping
41
+
42
+ Z: _pry_.switch
24
43
  Switch is a class, and every instance of Pry has an instance of Switch. This way we can
25
44
  access _pry_.switch. In the global scope there will be an object called 'switch' that will
26
45
  be an alias to _pry_.switch so that we can call its public methods. There will also be a
@@ -39,11 +58,11 @@ _pry_.switch
39
58
 
40
59
  Or we can use tab completion to present the menu by invoking switch as a global object.
41
60
 
42
- ````
61
+ ````
43
62
  [1] pry(main)> switch.m[TAB]
44
63
  switch.metafieldseditor switch.morfars-metafields
45
64
  [2] pry(main)> switch.mo[TAB]rfars-metafields
46
- ````
65
+ ````
47
66
 
48
67
  to accomplish the same.
49
68
 
@@ -52,7 +71,7 @@ _pry_.switch
52
71
 
53
72
  So in a deep menu we might see:
54
73
 
55
- ````
74
+ ````
56
75
  [1] pry(main)> switch
57
76
  current shop: none
58
77
 
@@ -79,7 +98,7 @@ _pry_.switch
79
98
  2. the thing you wanted
80
99
  [1] pry(main)> switch 2
81
100
  current shop: none switching to "the thing you wanted"...
82
- ````
101
+ ````
83
102
 
84
103
  # To check out
85
104
 
@@ -89,8 +108,8 @@ https://github.com/cldwalker/bond
89
108
 
90
109
  # Menu of Shops in local apps
91
110
  - [x] run rake shops in chosen local app
92
- - [ ] display result of rake shops in a menu
93
- - how do we handle this? do we use letters? or does switch command remember state (which menu was displayed last)? ie, what does ```switch 1``` mean?
111
+ - [x] display result of rake shops in a menu
112
+ - [x] how do we handle this? do we use letters? or does switch command remember state (which menu was displayed last)? ie, what does ```switch 1``` mean?
94
113
  - [ ] memoize results of rake shops in a hash with same keys as the apps have in config (I would put this in config). This is because running rake shops is slow enough to be annoying.
95
114
  - [ ] add -r,--refresh option to switch command to tell it to get fresh data
96
115
  - [ ] deploy apps with shopify_dev gem
@@ -102,6 +121,5 @@ https://github.com/cldwalker/bond
102
121
 
103
122
 
104
123
  # Using pry features
105
- https://github.com/ConradIrwin/pry-rescue
106
- -- we **really** want to be using this in test/development environments in rails apps.
124
+ https://github.com/ConradIrwin/pry-rescue -- we **really** want to be using this in test/development environments in rails apps.
107
125
  https://github.com/envygeeks/pry-vterm_aliases
@@ -1,4 +1,5 @@
1
1
  require 'shopifydev/pry/commands'
2
+ require 'shopifydev/pry/save_json'
2
3
  require 'shopifydev/shopify_api/caches'
3
4
 
4
5
  require 'term/ansicolor'
@@ -13,3 +14,5 @@ class Color
13
14
  end
14
15
  end
15
16
  end
17
+
18
+ Pry.config.hooks.add_hook(:before_session, :set_context) { |_, _, pry| pry.input = StringIO.new("cd ShopifyAPI") }
@@ -1,11 +1,179 @@
1
+ # encoding: UTF-8
1
2
  require 'oj'
2
3
 
3
- class LocalShopifyApp
4
+ class Switch
5
+ def initialize
6
+ @current_shop = ''
7
+ @menu = default_menu
8
+ end
9
+
10
+ def current_shop
11
+ @current_shop = ShopifyAPI::Base.site || 'none'
12
+ Color.green{ "current shop:"} + " #{@current_shop}"
13
+ end
14
+
15
+ def reset
16
+ @menu = default_menu
17
+ end
18
+
19
+ def menu
20
+ @menu
21
+ end
22
+
23
+ def pick(ix)
24
+ result = ''
25
+
26
+ # TODO we need need need to rename cfg, as it is currently confusing
27
+ @breadcrumbs, @cfg = pick_config(ix)
28
+
29
+ if @breadcrumbs == :no_such_config
30
+ result << Color.red{ "I don't know about #{ix}\n" }
31
+ result << self.menu.print
32
+ else
33
+ # update the menu based on the choice
34
+ # if we've reached a terminal menu, then do something
35
+ # otherwise just present the next menu
36
+ result << handle_choice
37
+ end
38
+ end
39
+
40
+ private
41
+
42
+ def set_shop(key, password, domain)
43
+ @current_shop = domain
44
+ ShopifyAPI::Base.site = "https://#{key}:#{password}@#{domain}/admin/"
45
+ @current_shop
46
+ end
47
+
48
+ def pick_config(ix)
49
+ # this gives us the menu item
50
+ path = self.menu.pick(ix)
51
+ return :no_such_config if path.nil?
52
+ result = shopify_config
53
+
54
+ path.each do |x|
55
+ result = result[x]
56
+ end
57
+
58
+ [path, result]
59
+ end
60
+
61
+ # if we chose a test shop cfg is a hash of key, password, and domain
62
+ # if we chose a local shop, it is a path
63
+ # path is the path through the yaml file
64
+ def handle_choice
65
+ result = ''
66
+
67
+ case @cfg.class.to_s
68
+ when "String" then
69
+ case @breadcrumbs[1].to_sym
70
+ when :development then menu_method = self.method(:development_menu)
71
+ when :heroku then menu_method = self.method(:heroku_menu)
72
+ else menu_method = self.method(:missing_menu)
73
+ end
74
+ else result = handle_by_shop_type
75
+ end
76
+
77
+ if menu_method
78
+ result << "you picked #{@breadcrumbs.join('.')}\n"
79
+ result << @cfg.inspect + "\n"
80
+ result << Color.yellow { menu_method.call.print }
81
+ end
82
+ result
83
+ end
84
+
85
+ def handle_by_shop_type
86
+ if @cfg.keys.include?("shop_type")
87
+ result = case @cfg["shop_type"].to_sym
88
+ when :local then "local"
89
+ when :heroku then "heroku"
90
+ else "something else"
91
+ end
92
+ else
93
+ set_shop(@cfg[:api_key], @cfg[:password], @cfg[:myshopify_domain])
94
+ result = self.current_shop
95
+ end
96
+
97
+ result
98
+ end
99
+
100
+ def default_menu
101
+ @menu = ConfigMenu.new(Shopifydev::Config.config, :default).build
102
+ end
103
+
104
+ # TODO this needs to be renamed:
105
+ # It is the contents of .shopifydev.yaml, but it is also
106
+ # more than that, since it gets updated throughout the life
107
+ # of a switch object.
108
+ def shopify_config
109
+ @shopify_config ||= Shopifydev::Config.config
110
+ end
111
+
112
+ # TODO this method is pretty obscure
113
+ def development_menu
114
+ # this needs to be memoized
115
+ app = LocalShopifyApp.new(@cfg)
116
+ shops = app.shops
117
+
118
+ # add the shop_type to the array of shops
119
+ shops.each do |shop|
120
+ shop["shop_type"] = "local"
121
+ end
122
+
123
+ key = ''
124
+ domain = @cfg # at this point we know @cfg is a path on the local machine
125
+
126
+ # iterate over shopifydev.yaml and replace the local file path matching
127
+ # domain with the list of shops associated with that domain
128
+ # TODO drop M's terrible habbit of using k and v for key and value
129
+ shopify_config["apps"]["development"].each do |k, v|
130
+ if v == domain
131
+ shopify_config["apps"]["development"][k] = shops
132
+ key = k
133
+ break
134
+ end
135
+ end
136
+
137
+ # the menu relevant yaml needs to be [key, array]
138
+ @menu = ConfigMenu.new([key, shopify_config["apps"]["development"][key]], :development).build
139
+ end
140
+
141
+ def heroku_menu
142
+ app = HerokuShopifyApp.new(@cfg)
143
+ shops = app.shops
144
+ @menu = ConfigMenu.new(shops, :heroku).build
145
+ end
146
+
147
+ def missing_menu
148
+ @menu = ConfigMenu.new(shops, :missing).build
149
+ end
150
+ end
151
+
152
+ class Pry
153
+ attr_accessor :switch
154
+
155
+ def switch
156
+ @switch ||= Switch.new
157
+ end
158
+ end
159
+
160
+ # these mini classes JUST grabs the JSON that we need for making submenus
161
+ class ShopifyAppShopList
4
162
  attr_accessor :path
163
+
5
164
  def initialize(path)
6
165
  @path = path
7
166
  end
8
167
 
168
+ def shops
169
+ raise "you must define the shops method"
170
+ end
171
+ end
172
+
173
+ class HerokuShopifyApp < ShopifyAppShopList
174
+ end
175
+
176
+ class LocalShopifyApp < ShopifyAppShopList
9
177
  def shops
10
178
  json = `/bin/bash -l -c "unset BUNDLE_GEMFILE; cd #{path} 2> /dev/null; bundle exec rake shops 2>/dev/null"`
11
179
  json = json.split("----snip----\n").last
@@ -15,65 +183,94 @@ class LocalShopifyApp
15
183
  end
16
184
 
17
185
  class ConfigMenu
18
- attr_accessor :cfg
186
+ attr_accessor :json
19
187
 
20
- def initialize(cfg)
21
- @cfg = cfg
22
- @menu_choices = [:do_nothing]
23
- @menu_display = []
188
+ def initialize(json, style=:default)
189
+ @json = json
190
+ @style = style
191
+ @choices = [:do_nothing]
192
+ @lines = []
24
193
  end
25
194
 
26
195
  def build
196
+ case @style
197
+ when :development then build_development
198
+ when :default then build_default
199
+ when :heroku then build_heroku
200
+ else build_missing
201
+ end
202
+ end
203
+
204
+ def print(output=nil)
205
+ if output.nil?
206
+ @lines.join("\n")
207
+ else
208
+ output.puts @lines.join("\n")
209
+ end
210
+ end
211
+
212
+ def pick(ix)
213
+ if ix >= @choices.length
214
+ nil
215
+ else
216
+ @choices[ix]
217
+ end
218
+ end
219
+
220
+ private
221
+
222
+ # instead of having infinite build_something methods, maybe we should have
223
+ # a way of passing in blocks, or something?
224
+ def build_default
27
225
  header("Test Shops")
28
- cfg[:test_shops].keys.each do |k|
226
+ json[:test_shops].keys.each do |k|
29
227
  choice([:test_shops, k], k)
30
228
  end
31
-
229
+
32
230
  header("Local Apps")
33
- cfg[:apps][:development].each do |k, path|
231
+ json[:apps][:development].each do |k, path|
34
232
  choice([:apps, :development, k], path)
35
233
  end
36
234
 
37
235
  header("Heroku Apps")
38
- cfg[:apps][:heroku].each do |k, name|
236
+ json[:apps][:heroku].each do |k, name|
39
237
  choice([:apps, :heroku, k], name)
40
238
  end
41
239
 
42
240
  self
43
241
  end
44
242
 
45
- def print(output)
46
- output.puts @menu_display.join("\n")
47
- end
243
+ def build_development
244
+ header("Development Shops")
48
245
 
49
- def header(label)
50
- @menu_display << ''
51
- @menu_display << Color.blue { label }
246
+ name = json.first
247
+ json.last.each_with_index do |h, index|
248
+ choice([:apps, :development, name, index], h["url"])
249
+ end
250
+
251
+ self
52
252
  end
53
253
 
54
- def choice(path, value)
55
- ix = @menu_choices.length
56
- @menu_display << Color.yellow{ ix.to_s } + '. ' + value.to_s
57
- @menu_choices[ix] = path
254
+ def build_missing
255
+ warn("AND I DON'T EVEN KNOW!")
256
+ self
58
257
  end
59
258
 
60
- def pick(ix)
61
- if ix >= @menu_choices.length
62
- nil
63
- else
64
- @menu_choices[ix]
65
- end
259
+ # TODO I think these three related methods could be moved into a module called "Writer" or something
260
+ def header(label)
261
+ @lines << ''
262
+ @lines << Color.blue { label }
66
263
  end
67
264
 
68
- def pick_config(ix)
69
- path = pick(ix)
70
- return :no_such_config if path.nil?
71
- result = cfg
72
- path.each do |x|
73
- result = result[x]
74
- end
265
+ def warn(label)
266
+ @lines << ''
267
+ @lines << Color.red { label }
268
+ end
75
269
 
76
- [path, result]
270
+ def choice(path, value)
271
+ ix = @choices.length
272
+ @lines << Color.yellow{ ix.to_s } + '. ' + value.to_s
273
+ @choices[ix] = path
77
274
  end
78
275
  end
79
276
 
@@ -81,99 +278,48 @@ shopifydev_command_set = Pry::CommandSet.new do
81
278
  create_command "switch" do
82
279
  description "switch shops"
83
280
 
84
-
85
281
  # opt is a Slop object, see https://github.com/injekt/slop/blob/master/README.md
86
282
  def options(opt)
87
283
  end
88
284
 
89
285
  def process
90
- print_current_shop
91
-
92
- config_menu = ConfigMenu.new(Shopifydev::Config.config).build
286
+ output.puts _pry_.switch.current_shop
93
287
 
94
288
  case true
95
289
  when args.empty?
96
- config_menu.print(output)
290
+ _pry_.switch.reset # reset to the first menu page
291
+ output.puts _pry_.switch.menu.print
292
+ print "ima ask for input:"
293
+ choice = $stdin.gets
294
+ puts "you chose #{choice}"
97
295
  when (args.length == 1)
98
296
  ix = args.first.to_i
99
- path, cfg = config_menu.pick_config(ix)
100
- if path == :no_such_config
101
- output.puts Color.red{ "I don't know about #{ix}" }
102
- config_menu.print(output)
103
- else
104
- handle_choice(path, cfg)
105
- end
106
- end
107
- end
108
-
109
- def print_current_shop
110
- current_shop = ShopifyAPI::Base.site || 'none'
111
- output.puts Color.green{ "current shop:"} + " #{current_shop}"
112
- end
113
-
114
- def handle_choice(path, cfg)
115
- case path.first.to_sym
116
- when :test_shops
117
- url = "https://#{cfg[:api_key]}:#{cfg[:password]}@#{cfg[:myshopify_domain]}/admin/"
118
- ShopifyAPI::Base.site = url
119
- print_current_shop
120
- when :apps
121
- case path[1].to_sym
122
- when :development
123
- output.puts "you picked #{path.join('.')}"
124
- output.puts cfg.inspect
125
- app = LocalShopifyApp.new(cfg)
126
- output.puts Color.yellow{ app.shops.inspect }
127
- when :heroku
128
- output.puts "you picked #{path.join('.')}"
129
- output.puts cfg.inspect
130
-
131
- output.puts Color.yellow{ "but it's not ready yet!"}
132
- else
133
- output.puts "you picked #{path.join('.')}"
134
- output.puts cfg.inspect
135
- output.puts Color.red{ "AND I DON'T EVEN KNOW!"}
136
- end
137
- else
138
- output.puts "you picked #{path.join('.')}"
139
- output.puts cfg.inspect
140
- output.puts Color.red{ "AND I DON'T EVEN KNOW!"}
297
+ output.puts _pry_.switch.pick(ix)
141
298
  end
142
299
  end
300
+ end
143
301
 
144
-
145
- def output_menu_choices(arr, ix=1)
146
- my_ix = 0
147
- arr.each do |item|
148
- output.puts menu_choice(ix+my_ix, item.to_s)
149
- my_ix +=1
302
+ create_command "arlog", "Turn ActiveResource logging on/off" do
303
+ def process
304
+ case args.first
305
+ when 'off'
306
+ puts Color.black{"ActiveResource logging "} + Color.red{'off'}
307
+ ActiveResource::Base.logger = nil
308
+ else
309
+ puts Color.black{"ActiveResource logging "} + Color.yellow{'on'}
310
+ ActiveResource::Base.logger = Logger.new STDOUT
150
311
  end
151
- my_ix
152
312
  end
313
+ end
153
314
 
154
- def menu_choice(ix, s)
155
- Color.yellow{ ix.to_s } + '. ' + s.to_s
156
- end
157
-
158
- def menu_header(s)
159
- Color.blue { s }
160
- end
161
-
162
- def write_menu(cfg)
163
- ix = 1
164
- # output.puts "Test Shops"
165
- output.puts menu_header("Test Shops")
166
- ix += output_menu_choices(cfg[:test_shops].keys.sort, ix)
167
-
168
- output.puts
169
- output.puts menu_header("Local Apps")
170
- ix += output_menu_choices(cfg[:apps][:development].keys.sort, ix)
315
+ block_command "tree", "display directory using unix 'tree'" do |path|
316
+ dir ||= Pathname.getwd
317
+ dir = Pathname.new(dir) unless dir.is_a?(Pathname)
318
+ puts Color.blue{ "listing #{dir}..."}
319
+ puts `cd #{dir.expand_path.to_s}; tree`.gsub(%r{(^[^\w]+)}, Color.black{'\1'})
171
320
 
172
- output.puts
173
- output.puts menu_header("Heroku Apps")
174
- ix += output_menu_choices(cfg[:apps][:heroku].keys.sort, ix)
175
- end
176
321
  end
322
+
177
323
  end
178
324
 
179
325
  Pry::Commands.import shopifydev_command_set
@@ -0,0 +1,78 @@
1
+ module Kernel
2
+ def save_json(obj, path=nil)
3
+ json = Oj.dump(obj, object:true, circular:true)
4
+ path = UnixTree.get_path(path, require: :file, new: true)
5
+ if path
6
+ puts Color.green{"writing json to #{path.to_s}..."}
7
+ File.open(path, 'w'){|f| f.write(json)}
8
+ true
9
+ else
10
+ false
11
+ end
12
+ end
13
+
14
+ def load_json(path=nil)
15
+ path = UnixTree.get_path(path, require: :file)
16
+ if path
17
+ puts Color.green{"loading json from #{path.to_s}..."}
18
+ Oj.load(path)
19
+ else
20
+ nil
21
+ end
22
+ end
23
+
24
+ end
25
+
26
+ module UnixTree
27
+ class << self
28
+ def get_path(path, opts={})
29
+ path = Pathname.new(path) unless path.nil?
30
+ while path.nil? || !viable_path(path, opts) do
31
+ missing = nil
32
+ path.expand_path.descend{|p| unless p.exist?; missing = p; break; end} if path
33
+ if missing
34
+ what = (missing == path) ? opts[:require].to_s : 'directory'
35
+ puts Color.red{ "couldn't find #{what} #{missing.to_s}" }
36
+ missing = missing.dirname
37
+ print_tree missing
38
+
39
+ end
40
+ print Color.yellow{ "enter path: "}
41
+ in_path = $stdin.gets.chomp
42
+ return nil if in_path == 'q'
43
+ unless in_path.blank?
44
+ in_path = Pathname(in_path)
45
+ path = missing if missing
46
+ path ||= Pathname.getwd
47
+ path = in_path.relative? ? path.join(in_path) : in_path
48
+ end
49
+ end
50
+ path.expand_path
51
+ end
52
+
53
+ def viable_path(path, opts={})
54
+ path = Pathname(path) unless path.is_a?(Pathname)
55
+ if opts[:new]
56
+ return false unless path.dirname.expand_path.exist?
57
+ else
58
+ return false unless path.expand_path.exist?
59
+ end
60
+ case opts[:require]
61
+ when :file
62
+ opts[:new] ? !(path.exist? && path.directory?) : path.expand_path.file?
63
+ when :directory
64
+ opts[:new] ? !path.exist? : path.expand_path.directory?
65
+ else
66
+ true
67
+ end
68
+ end
69
+
70
+ def print_tree(path=nil)
71
+ path ||= Pathname.getwd
72
+ path = Pathname.new(path) unless path.is_a?(Pathname)
73
+ path = path.dirname if path.file?
74
+ puts Color.blue{ "listing #{path}..."}
75
+ puts `cd #{path.expand_path.to_s}; tree`.gsub(%r{(^[^\w]+)}, Color.black{'\1'})
76
+ end
77
+ end
78
+ end
@@ -1,5 +1,3 @@
1
- puts "yo, included"
2
-
3
1
  module Shopifydev
4
2
  module ShopifyAPI
5
3
  module DirtyCache
@@ -1,3 +1,3 @@
1
1
  module Shopifydev
2
- VERSION = "0.0.2"
2
+ VERSION = "0.0.3"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: shopifydev
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -222,6 +222,7 @@ files:
222
222
  - lib/shopifydev/generators/templates/rvmrc
223
223
  - lib/shopifydev/generators/templates/shopify-tmbundle
224
224
  - lib/shopifydev/pry/commands.rb
225
+ - lib/shopifydev/pry/save_json.rb
225
226
  - lib/shopifydev/railtie.rb
226
227
  - lib/shopifydev/shop.rb
227
228
  - lib/shopifydev/shopify_api/caches.rb
@@ -249,7 +250,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
249
250
  version: '0'
250
251
  segments:
251
252
  - 0
252
- hash: -20439056481340104
253
+ hash: 3714550711815646135
253
254
  required_rubygems_version: !ruby/object:Gem::Requirement
254
255
  none: false
255
256
  requirements:
@@ -258,7 +259,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
258
259
  version: '0'
259
260
  segments:
260
261
  - 0
261
- hash: -20439056481340104
262
+ hash: 3714550711815646135
262
263
  requirements: []
263
264
  rubyforge_project:
264
265
  rubygems_version: 1.8.25