shopify_theme 0.0.10 → 0.0.11
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/.travis.yml +4 -0
- data/README.md +6 -3
- data/Rakefile +12 -0
- data/lib/shopify_theme.rb +61 -5
- data/lib/shopify_theme/cli.rb +15 -5
- data/lib/shopify_theme/version.rb +1 -1
- data/shopify_theme.gemspec +4 -2
- data/spec/spec_helper.rb +1 -0
- data/spec/unit/cli_spec.rb +27 -0
- metadata +50 -23
data/.travis.yml
ADDED
data/README.md
CHANGED
@@ -16,7 +16,9 @@ Generate the config file. Go get a valid api_key and password for your store hea
|
|
16
16
|
theme configure api_key password store_url
|
17
17
|
````
|
18
18
|
|
19
|
-
Example of config.yml. Notice store has no http or https declaration.
|
19
|
+
Example of config.yml. Notice store has no http or https declaration. You can
|
20
|
+
use `:whitelist_files:` to specify files for upload. The `assets/`, `config/`,
|
21
|
+
`layout/`, `snippets/` and `templates/` directories are included by default.
|
20
22
|
|
21
23
|
````
|
22
24
|
---
|
@@ -24,8 +26,9 @@ Example of config.yml. Notice store has no http or https declaration.
|
|
24
26
|
:password: 552338ce0d3aba7fc501dcf99bc57a81
|
25
27
|
:store: little-plastics.myshopify.com
|
26
28
|
:theme_id:
|
27
|
-
:
|
28
|
-
-
|
29
|
+
:whitelist_files:
|
30
|
+
- directoryToUpload/
|
31
|
+
- importantFile.txt
|
29
32
|
````
|
30
33
|
|
31
34
|
Download all the theme files
|
data/Rakefile
CHANGED
@@ -1,2 +1,14 @@
|
|
1
1
|
require 'bundler'
|
2
|
+
require 'rake/testtask'
|
2
3
|
Bundler::GemHelper.install_tasks
|
4
|
+
|
5
|
+
task :default => [:spec]
|
6
|
+
|
7
|
+
Rake::TestTask.new 'spec' do |t|
|
8
|
+
ENV['test'] = 'true'
|
9
|
+
t.libs = ['lib', 'spec']
|
10
|
+
t.ruby_opts << '-rubygems'
|
11
|
+
t.verbose = true
|
12
|
+
t.test_files = FileList['spec/**/*_spec.rb']
|
13
|
+
end
|
14
|
+
|
data/lib/shopify_theme.rb
CHANGED
@@ -3,11 +3,48 @@ module ShopifyTheme
|
|
3
3
|
include HTTParty
|
4
4
|
|
5
5
|
NOOPParser = Proc.new {|data, format| {} }
|
6
|
+
TIMER_RESET = 5 * 60 + 5
|
7
|
+
PERMIT_LOWER_LIMIT = 10
|
8
|
+
|
9
|
+
def self.test?
|
10
|
+
ENV['test']
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.manage_timer(response)
|
14
|
+
@@current_api_call_count, @@total_api_calls = response.headers['x-shopify-shop-api-call-limit'].split('/')
|
15
|
+
@@current_timer = Time.now if @current_timer.nil?
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.critical_permits?
|
19
|
+
@@total_api_calls.to_i - @@current_api_call_count.to_i < PERMIT_LOWER_LIMIT
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.passed_api_refresh?
|
23
|
+
delta_seconds > TIMER_RESET
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.delta_seconds
|
27
|
+
Time.now.to_i - @@current_timer.to_i
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.needs_sleep?
|
31
|
+
critical_permits? && !passed_api_refresh?
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.sleep
|
35
|
+
if needs_sleep?
|
36
|
+
Kernel.sleep(TIMER_RESET - delta_seconds)
|
37
|
+
@current_timer = nil
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
6
41
|
|
7
42
|
def self.asset_list
|
8
43
|
# HTTParty parser chokes on assest listing, have it noop
|
9
44
|
# and then use a rel JSON parser.
|
10
45
|
response = shopify.get(path, :parser => NOOPParser)
|
46
|
+
manage_timer(response)
|
47
|
+
|
11
48
|
assets = JSON.parse(response.body)["assets"].collect {|a| a['key'] }
|
12
49
|
# Remove any .css files if a .css.liquid file exists
|
13
50
|
assets.reject{|a| assets.include?("#{a}.liquid") }
|
@@ -15,20 +52,35 @@ module ShopifyTheme
|
|
15
52
|
|
16
53
|
def self.get_asset(asset)
|
17
54
|
response = shopify.get(path, :query =>{:asset => {:key => asset}}, :parser => NOOPParser)
|
55
|
+
manage_timer(response)
|
56
|
+
|
18
57
|
# HTTParty json parsing is broken?
|
19
|
-
JSON.parse(response.body)["asset"]
|
58
|
+
asset = response.code == 200 ? JSON.parse(response.body)["asset"] : {}
|
59
|
+
asset['response'] = response
|
60
|
+
asset
|
20
61
|
end
|
21
62
|
|
22
63
|
def self.send_asset(data)
|
23
|
-
shopify.put(path, :body =>{:asset => data})
|
64
|
+
response = shopify.put(path, :body =>{:asset => data})
|
65
|
+
manage_timer(response)
|
66
|
+
response
|
24
67
|
end
|
25
68
|
|
26
69
|
def self.delete_asset(asset)
|
27
|
-
shopify.delete(path, :body =>{:asset => {:key => asset}})
|
70
|
+
response = shopify.delete(path, :body =>{:asset => {:key => asset}})
|
71
|
+
manage_timer(response)
|
72
|
+
response
|
28
73
|
end
|
29
74
|
|
30
75
|
def self.config
|
31
|
-
@config ||=
|
76
|
+
@config ||= if File.exist? 'config.yml'
|
77
|
+
config = YAML.load(File.read('config.yml'))
|
78
|
+
puts ":ignore_files: is deprecated for a white list, use :whitelist_files: instead" if config[:ignore_files] && !test?
|
79
|
+
config
|
80
|
+
else
|
81
|
+
puts "config.yml does not exist!" unless test?
|
82
|
+
{}
|
83
|
+
end
|
32
84
|
end
|
33
85
|
|
34
86
|
def self.path
|
@@ -36,7 +88,11 @@ module ShopifyTheme
|
|
36
88
|
end
|
37
89
|
|
38
90
|
def self.ignore_files
|
39
|
-
@ignore_files ||= (config[:ignore_files] || []).compact.
|
91
|
+
@ignore_files ||= (config[:ignore_files] || []).compact.map { |r| Regexp.new(r) }
|
92
|
+
end
|
93
|
+
|
94
|
+
def self.whitelist_files
|
95
|
+
@whitelist_files ||= (config[:whitelist_files] || []).compact
|
40
96
|
end
|
41
97
|
|
42
98
|
def self.is_binary_data?(string)
|
data/lib/shopify_theme/cli.rb
CHANGED
@@ -14,6 +14,7 @@ module ShopifyTheme
|
|
14
14
|
|
15
15
|
BINARY_EXTENSIONS = %w(png gif jpg jpeg eot svg ttf woff otf swf ico)
|
16
16
|
IGNORE = %w(config.yml)
|
17
|
+
DEFAULT_WHITELIST = %w(layout/ assets/ config/ snippets/ templates/)
|
17
18
|
TIMEFORMAT = "%H:%M:%S"
|
18
19
|
|
19
20
|
tasks.keys.abbrev.each do |shortcut, command|
|
@@ -31,7 +32,7 @@ module ShopifyTheme
|
|
31
32
|
|
32
33
|
desc "configure API_KEY PASSWORD STORE THEME_ID", "generate a config file for the store to connect to"
|
33
34
|
def configure(api_key=nil, password=nil, store=nil, theme_id=nil)
|
34
|
-
config = {:api_key => api_key, :password => password, :store => store, :theme_id => theme_id
|
35
|
+
config = {:api_key => api_key, :password => password, :store => store, :theme_id => theme_id}
|
35
36
|
create_file('config.yml', config.to_yaml)
|
36
37
|
end
|
37
38
|
|
@@ -120,14 +121,18 @@ module ShopifyTheme
|
|
120
121
|
private
|
121
122
|
|
122
123
|
def local_assets_list
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
end
|
124
|
+
local_files.reject do |p|
|
125
|
+
@permitted_files ||= (DEFAULT_WHITELIST | ShopifyTheme.whitelist_files).map{|pattern| Regexp.new(pattern)}
|
126
|
+
@permitted_files.none? { |regex| regex =~ p }
|
127
127
|
end
|
128
128
|
end
|
129
129
|
|
130
|
+
def local_files
|
131
|
+
Dir.glob(File.join('**', '*'))
|
132
|
+
end
|
133
|
+
|
130
134
|
def download_asset(key)
|
135
|
+
notify_and_sleep("Approaching limit of API permits. Naptime until more permits become available!") if ShopifyTheme.needs_sleep?
|
131
136
|
asset = ShopifyTheme.get_asset(key)
|
132
137
|
if asset['value']
|
133
138
|
# For CRLF line endings
|
@@ -169,6 +174,11 @@ module ShopifyTheme
|
|
169
174
|
end
|
170
175
|
end
|
171
176
|
|
177
|
+
def notify_and_sleep(message)
|
178
|
+
say(message, :red)
|
179
|
+
ShopifyTheme.sleep
|
180
|
+
end
|
181
|
+
|
172
182
|
def errors_from_response(response)
|
173
183
|
return unless response.parsed_response
|
174
184
|
|
data/shopify_theme.gemspec
CHANGED
@@ -13,13 +13,15 @@ Gem::Specification.new do |s|
|
|
13
13
|
s.description = %q{Command line tool to help with developing Shopify themes. Provides simple commands to download, upload and delete files from a theme. Also includes the watch command to watch a directory and upload files as they change.}
|
14
14
|
|
15
15
|
s.rubyforge_project = "shopify_theme"
|
16
|
-
s.add_development_dependency 'rake'
|
17
16
|
s.add_dependency("thor", [">= 0.14.4"])
|
18
17
|
s.add_dependency("httparty", "~> 0.11")
|
19
|
-
s.add_dependency("json")
|
18
|
+
s.add_dependency("json", "~> 1.5.4")
|
20
19
|
s.add_dependency("listen", "~>1.0")
|
21
20
|
s.add_dependency("launchy")
|
22
21
|
|
22
|
+
s.add_development_dependency 'rake'
|
23
|
+
s.add_development_dependency 'minitest', '>= 5.0.0'
|
24
|
+
|
23
25
|
s.files = `git ls-files`.split("\n")
|
24
26
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
25
27
|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'minitest/autorun'
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'shopify_theme'
|
3
|
+
require 'shopify_theme/cli'
|
4
|
+
|
5
|
+
module ShopifyTheme
|
6
|
+
describe "Cli" do
|
7
|
+
|
8
|
+
class CliDouble < Cli
|
9
|
+
attr_writer :local_files
|
10
|
+
|
11
|
+
desc "", ""
|
12
|
+
def local_files
|
13
|
+
@local_files
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
before do
|
18
|
+
@cli = CliDouble.new
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should remove assets that are not a part of the white list" do
|
22
|
+
@cli.local_files = ['assets/image.png', 'config.yml', 'layout/theme.liquid']
|
23
|
+
assert_equal 2, @cli.send(:local_assets_list).length
|
24
|
+
assert_equal false, @cli.send(:local_assets_list).include?('config.yml')
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: shopify_theme
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.11
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,24 +9,8 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-11-04 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
|
-
- !ruby/object:Gem::Dependency
|
15
|
-
name: rake
|
16
|
-
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
|
-
requirements:
|
19
|
-
- - ! '>='
|
20
|
-
- !ruby/object:Gem::Version
|
21
|
-
version: '0'
|
22
|
-
type: :development
|
23
|
-
prerelease: false
|
24
|
-
version_requirements: !ruby/object:Gem::Requirement
|
25
|
-
none: false
|
26
|
-
requirements:
|
27
|
-
- - ! '>='
|
28
|
-
- !ruby/object:Gem::Version
|
29
|
-
version: '0'
|
30
14
|
- !ruby/object:Gem::Dependency
|
31
15
|
name: thor
|
32
16
|
requirement: !ruby/object:Gem::Requirement
|
@@ -64,17 +48,17 @@ dependencies:
|
|
64
48
|
requirement: !ruby/object:Gem::Requirement
|
65
49
|
none: false
|
66
50
|
requirements:
|
67
|
-
- -
|
51
|
+
- - ~>
|
68
52
|
- !ruby/object:Gem::Version
|
69
|
-
version:
|
53
|
+
version: 1.5.4
|
70
54
|
type: :runtime
|
71
55
|
prerelease: false
|
72
56
|
version_requirements: !ruby/object:Gem::Requirement
|
73
57
|
none: false
|
74
58
|
requirements:
|
75
|
-
- -
|
59
|
+
- - ~>
|
76
60
|
- !ruby/object:Gem::Version
|
77
|
-
version:
|
61
|
+
version: 1.5.4
|
78
62
|
- !ruby/object:Gem::Dependency
|
79
63
|
name: listen
|
80
64
|
requirement: !ruby/object:Gem::Requirement
|
@@ -107,6 +91,38 @@ dependencies:
|
|
107
91
|
- - ! '>='
|
108
92
|
- !ruby/object:Gem::Version
|
109
93
|
version: '0'
|
94
|
+
- !ruby/object:Gem::Dependency
|
95
|
+
name: rake
|
96
|
+
requirement: !ruby/object:Gem::Requirement
|
97
|
+
none: false
|
98
|
+
requirements:
|
99
|
+
- - ! '>='
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: '0'
|
102
|
+
type: :development
|
103
|
+
prerelease: false
|
104
|
+
version_requirements: !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
106
|
+
requirements:
|
107
|
+
- - ! '>='
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0'
|
110
|
+
- !ruby/object:Gem::Dependency
|
111
|
+
name: minitest
|
112
|
+
requirement: !ruby/object:Gem::Requirement
|
113
|
+
none: false
|
114
|
+
requirements:
|
115
|
+
- - ! '>='
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: 5.0.0
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
none: false
|
122
|
+
requirements:
|
123
|
+
- - ! '>='
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: 5.0.0
|
110
126
|
description: Command line tool to help with developing Shopify themes. Provides simple
|
111
127
|
commands to download, upload and delete files from a theme. Also includes the watch
|
112
128
|
command to watch a directory and upload files as they change.
|
@@ -118,6 +134,7 @@ extensions: []
|
|
118
134
|
extra_rdoc_files: []
|
119
135
|
files:
|
120
136
|
- .gitignore
|
137
|
+
- .travis.yml
|
121
138
|
- Gemfile
|
122
139
|
- MIT-LICENSE
|
123
140
|
- README.md
|
@@ -127,6 +144,8 @@ files:
|
|
127
144
|
- lib/shopify_theme/cli.rb
|
128
145
|
- lib/shopify_theme/version.rb
|
129
146
|
- shopify_theme.gemspec
|
147
|
+
- spec/spec_helper.rb
|
148
|
+
- spec/unit/cli_spec.rb
|
130
149
|
homepage: https://github.com/Shopify/shopify_theme
|
131
150
|
licenses: []
|
132
151
|
post_install_message:
|
@@ -139,16 +158,24 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
139
158
|
- - ! '>='
|
140
159
|
- !ruby/object:Gem::Version
|
141
160
|
version: '0'
|
161
|
+
segments:
|
162
|
+
- 0
|
163
|
+
hash: 1305888406830472996
|
142
164
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
143
165
|
none: false
|
144
166
|
requirements:
|
145
167
|
- - ! '>='
|
146
168
|
- !ruby/object:Gem::Version
|
147
169
|
version: '0'
|
170
|
+
segments:
|
171
|
+
- 0
|
172
|
+
hash: 1305888406830472996
|
148
173
|
requirements: []
|
149
174
|
rubyforge_project: shopify_theme
|
150
175
|
rubygems_version: 1.8.23
|
151
176
|
signing_key:
|
152
177
|
specification_version: 3
|
153
178
|
summary: Command line tool for developing themes
|
154
|
-
test_files:
|
179
|
+
test_files:
|
180
|
+
- spec/spec_helper.rb
|
181
|
+
- spec/unit/cli_spec.rb
|