shopify_theme 0.0.23 → 0.0.24

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 6971fe42d85d617b5d0a95de3c9e34279dac2199
4
- data.tar.gz: d3ca43ec6f1b2ed28266e67a6036d748709a0f85
3
+ metadata.gz: 50c5d2b43b94c79a4bc37a4d3b71080f2d9e85fb
4
+ data.tar.gz: bcc2ec0776ca9e537601a94df1146c5ada57a23a
5
5
  SHA512:
6
- metadata.gz: 994ba6ea158f91729a131200ebc778c72467234febfa8716e72f829156c75fd028e6d9c085ba80bc6fa0bd7e9a5d6c11a7778db69d1bd42c06e37134abfb87e2
7
- data.tar.gz: 94ee9d1a1266d99e6b9a0f762e8bfe0e8cfa50bf09f2651a58d070e5de1c42e73020bfdadcfd3d45e1e51b8cbcb0ee54e2e83a9863dc8f1ad0f5a844c6e72592
6
+ metadata.gz: 75463c446905bc9d79d59e1b2e3fead8706624c605321f3582dbcdd61713d6b5fc4d8a9cf96d284323bc2f1b3339489fda0cfb7ba79557e9479e59a50c9af21d
7
+ data.tar.gz: 66c63f7bd44755b65773e8a3684dd49e9c951dbb8ac25b13d5ffcea63c1c7d0739188e3118a5b7c2705f67a5c6def6d2cceeceb64117233b2fca7c95341378d7
data/lib/shopify_theme.rb CHANGED
@@ -7,6 +7,8 @@ module ShopifyTheme
7
7
  NOOPParser = Proc.new {|data, format| {} }
8
8
  TIMER_RESET = 10
9
9
  PERMIT_LOWER_LIMIT = 3
10
+ MAX_TIMBER_RETRY = 5
11
+
10
12
 
11
13
  def self.test?
12
14
  ENV['test']
@@ -79,7 +81,7 @@ module ShopifyTheme
79
81
  response
80
82
  end
81
83
 
82
- def self.upload_timber(name, version)
84
+ def self.upload_timber(name, version, retries=0)
83
85
  release = Releases.new.find(version)
84
86
  response = shopify.post("/admin/themes.json", :body => {:theme => {:name => name, :src => release.zip_url, :role => 'unpublished'}})
85
87
  manage_timer(response)
@@ -87,6 +89,8 @@ module ShopifyTheme
87
89
  if theme = body['theme']
88
90
  puts "Successfully created #{name} using Shopify Timber #{version}"
89
91
  watch_until_processing_complete(theme)
92
+ elsif retries < MAX_TIMBER_RETRY
93
+ upload_timber(name, version, retries + 1)
90
94
  else
91
95
  puts "Could not download theme!"
92
96
  puts body
@@ -113,7 +117,7 @@ module ShopifyTheme
113
117
  end
114
118
 
115
119
  def self.ignore_files
116
- (config[:ignore_files] || []).compact.map { |r| Regexp.new(r) }
120
+ (config[:ignore_files] || []).compact
117
121
  end
118
122
 
119
123
  def self.whitelist_files
@@ -8,6 +8,7 @@ require 'json'
8
8
  require 'filewatcher'
9
9
  require 'launchy'
10
10
  require 'mimemagic'
11
+ require 'shopify_theme/file_filters'
11
12
 
12
13
  module ShopifyTheme
13
14
  EXTENSIONS = [
@@ -57,7 +58,7 @@ module ShopifyTheme
57
58
 
58
59
  desc "configure API_KEY PASSWORD STORE THEME_ID", "generate a config file for the store to connect to"
59
60
  def configure(api_key=nil, password=nil, store=nil, theme_id=nil)
60
- config = {:api_key => api_key, :password => password, :store => store, :theme_id => theme_id}
61
+ config = {:api_key => api_key, :password => password, :store => store, :theme_id => theme_id, :whitelist_files => Filters::Whitelist::DEFAULT_WHITELIST}
61
62
  create_file('config.yml', config.to_yaml)
62
63
  check(true)
63
64
  end
@@ -72,7 +73,7 @@ module ShopifyTheme
72
73
  method_option :master, :type => :boolean, :default => false
73
74
  method_option :version, :type => :string, :default => "latest"
74
75
  def bootstrap(api_key=nil, password=nil, store=nil, theme_name=nil)
75
- ShopifyTheme.config = {:api_key => api_key, :password => password, :store => store}
76
+ ShopifyTheme.config = {:api_key => api_key, :password => password, :store => store, :whitelist_files => Filters::Whitelist::DEFAULT_WHITELIST}
76
77
  check(true)
77
78
 
78
79
  theme_name ||= 'Timber'
@@ -98,7 +99,7 @@ module ShopifyTheme
98
99
  method_option :exclude
99
100
  def download(*keys)
100
101
  check(true)
101
- assets = keys.empty? ? ShopifyTheme.asset_list : keys
102
+ assets = assets_for(keys, ShopifyTheme.asset_list)
102
103
 
103
104
  if options['exclude']
104
105
  assets = assets.delete_if { |asset| asset =~ Regexp.new(options['exclude']) }
@@ -122,6 +123,7 @@ module ShopifyTheme
122
123
  method_option :quiet, :type => :boolean, :default => false
123
124
  def upload(*keys)
124
125
  check(true)
126
+ assets = assets_for(keys, local_assets_list)
125
127
  assets = keys.empty? ? local_assets_list : keys
126
128
  assets.each do |asset|
127
129
  send_asset(asset, options['quiet'])
@@ -192,6 +194,13 @@ module ShopifyTheme
192
194
  end
193
195
  end
194
196
 
197
+ def local_assets_list
198
+ FileFilters.new(
199
+ Filters::Whitelist.new(ShopifyTheme.whitelist_files),
200
+ Filters::Blacklist.new(ShopifyTheme.ignore_files)
201
+ ).select(local_files)
202
+ end
203
+
195
204
  protected
196
205
 
197
206
  def config
@@ -205,6 +214,10 @@ module ShopifyTheme
205
214
  end
206
215
 
207
216
  private
217
+ def assets_for(keys=[], files=[])
218
+ filter = FileFilters.new(Filters::CommandInput.new(keys))
219
+ filter.select(files)
220
+ end
208
221
 
209
222
  def watcher
210
223
  FileWatcher.new(Dir.pwd).watch() do |filename, event|
@@ -212,13 +225,6 @@ module ShopifyTheme
212
225
  end
213
226
  end
214
227
 
215
- def local_assets_list
216
- local_files.reject do |p|
217
- @permitted_files ||= (DEFAULT_WHITELIST | ShopifyTheme.whitelist_files).map{|pattern| Regexp.new(pattern)}
218
- @permitted_files.none? { |regex| regex =~ p } || ShopifyTheme.ignore_files.any? { |regex| regex =~ p }
219
- end
220
- end
221
-
222
228
  def local_files
223
229
  Dir.glob(File.join('**', '*')).reject do |f|
224
230
  File.directory?(f)
@@ -0,0 +1,18 @@
1
+ require 'shopify_theme/filters/blacklist'
2
+ require 'shopify_theme/filters/whitelist'
3
+ require 'shopify_theme/filters/command_input'
4
+
5
+ module ShopifyTheme
6
+ class FileFilters
7
+ def initialize(*filters)
8
+ raise ArgumentError, "Must have at least one filter to apply" unless filters.length > 0
9
+ @filters = filters
10
+ end
11
+
12
+ def select(list)
13
+ @filters.reduce(list) do |results, filter|
14
+ filter.select(results)
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,17 @@
1
+ module ShopifyTheme
2
+ module Filters
3
+ class Blacklist
4
+ attr_reader :patterns
5
+
6
+ def initialize(pattern_strings=[])
7
+ @patterns = pattern_strings.map { |p| Regexp.new(p)}
8
+ end
9
+
10
+ def select(list)
11
+ list.select do |entry|
12
+ patterns.none? { |pat| pat.match(entry) }
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ module ShopifyTheme
2
+ module Filters
3
+ class CommandInput
4
+ attr_reader :patterns
5
+ def initialize(inputs=[])
6
+ @patterns = inputs.map { |i| Regexp.compile(i) }
7
+ end
8
+
9
+ def select(list)
10
+ return list if patterns.empty?
11
+ list.select { |entry|
12
+ patterns.any? { |pat| pat.match(entry) }
13
+ }
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,19 @@
1
+ module ShopifyTheme
2
+ module Filters
3
+ class Whitelist
4
+ DEFAULT_WHITELIST = %w(layout/ assets/ config/ snippets/ templates/ locales/)
5
+
6
+ attr_reader :patterns
7
+
8
+ def initialize(pattern_strings=[])
9
+ @patterns = (pattern_strings.empty? ? DEFAULT_WHITELIST : pattern_strings).map { |pattern| Regexp.new(pattern) }
10
+ end
11
+
12
+ def select(list)
13
+ list.select do |entry|
14
+ patterns.any? { |pat| pat.match(entry) }
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -1,3 +1,3 @@
1
1
  module ShopifyTheme
2
- VERSION = "0.0.23"
2
+ VERSION = "0.0.24"
3
3
  end
@@ -36,17 +36,22 @@ module ShopifyTheme
36
36
 
37
37
  it "should remove assets that are not a part of the white list" do
38
38
  @cli.local_files = ['assets/image.png', 'config.yml', 'layout/theme.liquid', 'locales/en.default.json']
39
- local_assets_list = @cli.send(:local_assets_list)
40
- assert_equal 3, local_assets_list.length
41
- assert_equal false, local_assets_list.include?('config.yml')
39
+ assert_equal 3, @cli.local_assets_list.length
40
+ assert_equal false, @cli.local_assets_list.include?('config.yml')
41
+ end
42
+
43
+ it 'should only use the whitelist entries for determining which files to upload (bug #156)' do
44
+ @cli.local_files = %w(assets/application.css.liquid assets/application.js assets/image.png assets/bunny.jpg layout/index.liquid snippets/preview.liquid)
45
+ ShopifyTheme.config = {whitelist_files: %w(assets/application.css.liquid assets/application.js layout/ snippets/)}
46
+ assert_equal 4, @cli.local_assets_list.length
47
+ assert_equal false, @cli.local_assets_list.include?('assets/image.png')
42
48
  end
43
49
 
44
50
  it "should remove assets that are part of the ignore list" do
45
51
  ShopifyTheme.config = {ignore_files: ['config/settings.html']}
46
52
  @cli.local_files = ['assets/image.png', 'layout/theme.liquid', 'config/settings.html']
47
- local_assets_list = @cli.send(:local_assets_list)
48
- assert_equal 2, local_assets_list.length
49
- assert_equal false, local_assets_list.include?('config/settings.html')
53
+ assert_equal 2, @cli.local_assets_list.length
54
+ assert_equal false, @cli.local_assets_list.include?('config/settings.html')
50
55
  end
51
56
 
52
57
  it "should generate the shop path URL to the query parameter preview_theme_id if the id is present" do
@@ -0,0 +1,37 @@
1
+ require 'spec_helper'
2
+ require 'shopify_theme/file_filters'
3
+
4
+ module ShopifyTheme
5
+ describe "FileFilters" do
6
+ class IdentityFilter
7
+ def select(list)
8
+ list.select { true }
9
+ end
10
+ end
11
+
12
+ class EvenFilter
13
+ def select(list)
14
+ list.select { |i| i % 2 == 0 }
15
+ end
16
+ end
17
+
18
+ it "initializing without a filter raises an error" do
19
+ assert_raises ArgumentError do
20
+ FileFilters.new
21
+ end
22
+ end
23
+
24
+ it "initializing with a single filter" do
25
+ begin
26
+ FileFilters.new(IdentityFilter.new)
27
+ rescue Error => e
28
+ flunk("Initializing with a single filter should not fail. #{e}")
29
+ end
30
+ end
31
+
32
+ it "should only select entries that were valid for all of the given filters" do
33
+ filters = FileFilters.new(IdentityFilter.new, EvenFilter.new)
34
+ assert_equal [2, 4], filters.select([1, 2, 3, 4, 5])
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,32 @@
1
+ require 'spec_helper'
2
+ require 'shopify_theme/filters/blacklist'
3
+
4
+
5
+ module ShopifyTheme
6
+ module Filters
7
+ describe "Blacklist" do
8
+ TEST_PATHS = %w(
9
+ settings.html
10
+ config/item1.html
11
+ config/item2.html
12
+ config/item3.html
13
+ layout/thing1.html
14
+ assets/application.css.liquid
15
+ assets/application.js
16
+ templates/thing2.html
17
+ snippets/fancy.liquid
18
+ )
19
+
20
+ it "should return the entire list back if initialized with no patterns" do
21
+ blacklist = Blacklist.new
22
+ assert_equal TEST_PATHS, blacklist.select(TEST_PATHS)
23
+ end
24
+
25
+ it "should return everything except for the items that matched the pattern" do
26
+ blacklist = Blacklist.new(%w(config/* settings.html assets/* templates/* snippets/*))
27
+ assert_equal %w(layout/thing1.html), blacklist.select(TEST_PATHS)
28
+ end
29
+
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,18 @@
1
+ require 'spec_helper'
2
+ require 'shopify_theme/filters/command_input'
3
+
4
+ module ShopifyTheme
5
+ module Filters
6
+ describe "CommandInput" do
7
+ it "should return the entire list if initialized with nothing" do
8
+ filter = CommandInput.new([])
9
+ assert_equal %w(a b c d e f), filter.select(%w(a b c d e f))
10
+ end
11
+
12
+ it "should return a subset if initialized with some values" do
13
+ filter = CommandInput.new(%w(a c d))
14
+ assert_equal %w(a c d a), filter.select(%w(a b c d e a f))
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,41 @@
1
+ require 'spec_helper'
2
+ require 'shopify_theme/filters/whitelist'
3
+
4
+ module ShopifyTheme
5
+ module Filters
6
+ describe "Whitelist" do
7
+ TEST_PATHS = %w(
8
+ settings.html
9
+ config/item1.html
10
+ config/item2.html
11
+ config/item3.html
12
+ layout/thing1.html
13
+ assets/application.css.liquid
14
+ assets/application.js
15
+ templates/thing2.html
16
+ snippets/fancy.liquid
17
+ )
18
+
19
+ it "should use the default whitelist if nothing was provided" do
20
+ whitelist = Whitelist.new
21
+ expected = %w(
22
+ config/item1.html
23
+ config/item2.html
24
+ config/item3.html
25
+ layout/thing1.html
26
+ assets/application.css.liquid
27
+ assets/application.js
28
+ templates/thing2.html
29
+ snippets/fancy.liquid
30
+ )
31
+ assert_equal expected, whitelist.select(TEST_PATHS)
32
+ end
33
+
34
+ it "should ignore the default 1+ whitelists were provided" do
35
+ whitelist = Whitelist.new %w(settings.html config/item1.html config/item2.html config/item3.html layout/ templates/)
36
+ expected = %w(settings.html config/item1.html config/item2.html config/item3.html layout/thing1.html templates/thing2.html)
37
+ assert_equal expected, whitelist.select(TEST_PATHS)
38
+ end
39
+ end
40
+ end
41
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: shopify_theme
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.23
4
+ version: 0.0.24
5
5
  platform: ruby
6
6
  authors:
7
7
  - John Duff
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-09-01 00:00:00.000000000 Z
11
+ date: 2015-09-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor
@@ -174,6 +174,10 @@ files:
174
174
  - lib/shopify_theme.rb
175
175
  - lib/shopify_theme/api_checker.rb
176
176
  - lib/shopify_theme/cli.rb
177
+ - lib/shopify_theme/file_filters.rb
178
+ - lib/shopify_theme/filters/blacklist.rb
179
+ - lib/shopify_theme/filters/command_input.rb
180
+ - lib/shopify_theme/filters/whitelist.rb
177
181
  - lib/shopify_theme/releases.rb
178
182
  - lib/shopify_theme/version.rb
179
183
  - shipit.rubygems.yml
@@ -185,6 +189,10 @@ files:
185
189
  - spec/spec_helper.rb
186
190
  - spec/unit/api_checker_spec.rb
187
191
  - spec/unit/cli_spec.rb
192
+ - spec/unit/file_filters_spec.rb
193
+ - spec/unit/filters/blacklist_spec.rb
194
+ - spec/unit/filters/command_input_spec.rb
195
+ - spec/unit/filters/whitelist_spec.rb
188
196
  - spec/unit/releases_spec.rb
189
197
  homepage: https://github.com/Shopify/shopify_theme
190
198
  licenses: