shopifydev 0.0.1
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/.gitignore +17 -0
- data/.pryrc +3 -0
- data/.root.shopifydev.yaml.sample +21 -0
- data/.ruby-version +1 -0
- data/.shopifydev.yaml.sample +7 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/NEXTSTEPS.md +33 -0
- data/README.md +78 -0
- data/Rakefile +1 -0
- data/bin/shopify_console +15 -0
- data/bin/shopifydev +100 -0
- data/lib/rails/generators/shopifydev/shops_generator.rb +11 -0
- data/lib/rails/generators/shopifydev/templates/shops.rake +5 -0
- data/lib/rails/tasks/shops.rake +7 -0
- data/lib/shopifydev/asset.rb +58 -0
- data/lib/shopifydev/commands.rb +83 -0
- data/lib/shopifydev/config.rb +9 -0
- data/lib/shopifydev/generators/shop.rb +29 -0
- data/lib/shopifydev/generators/templates/Gemfile +10 -0
- data/lib/shopifydev/generators/templates/gitignore +1 -0
- data/lib/shopifydev/generators/templates/rvmrc +1 -0
- data/lib/shopifydev/generators/templates/shopify-tmbundle +21 -0
- data/lib/shopifydev/pry/commands.rb +194 -0
- data/lib/shopifydev/railtie.rb +11 -0
- data/lib/shopifydev/shop.rb +38 -0
- data/lib/shopifydev/template.rb +73 -0
- data/lib/shopifydev/version.rb +3 -0
- data/lib/shopifydev.rb +10 -0
- data/shopifydev.gemspec +35 -0
- data/spec/shopifydev/config_spec.rb +5 -0
- data/spec/shopifydev/generators/shopifydev/shopifydev_generator_spec.rb +5 -0
- data/spec/shopifydev/pry/commands_spec.rb +5 -0
- data/spec/shopifydev/railtie_spec.rb +5 -0
- data/templates/customers/order.liquid +109 -0
- data/templates/customers/register.liquid +42 -0
- data/templates/page.support.liquid +78 -0
- data/templates/page.verbose.liquid +18 -0
- data/templates/product.liquid +284 -0
- data/templates/search.liquid +63 -0
- data/test_driver.rb +31 -0
- metadata +275 -0
data/.gitignore
ADDED
data/.pryrc
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
test_shops:
|
2
|
+
cronin:
|
3
|
+
api_key: akey
|
4
|
+
password: aword
|
5
|
+
myshopify_domain: cronin-group3575.myshopify.com
|
6
|
+
schumm:
|
7
|
+
api_key: anotherkey
|
8
|
+
password: anotherword
|
9
|
+
myshopify_domain: schumm-durgan-and-lang94.myshopify.com
|
10
|
+
|
11
|
+
apps:
|
12
|
+
development:
|
13
|
+
meta: ~/clients/webify/metafieldeditor
|
14
|
+
ship: ~/clients/webify/shipping
|
15
|
+
|
16
|
+
heroku:
|
17
|
+
metafieldseditor: metafieldseditor
|
18
|
+
morfars-metafields: morfars-metafields
|
19
|
+
red-pepper-shipping: red-pepper-shipping
|
20
|
+
shipping-lifemap-bioreagents: shipping-lifemap-bioreagents
|
21
|
+
shipping-staging: shipping-staging
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
ruby-1.9.3-p429
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012 Michael Johnston
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/NEXTSTEPS.md
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
# switch command
|
2
|
+
|
3
|
+
should be some shortcuts
|
4
|
+
|
5
|
+
switch cronin
|
6
|
+
|
7
|
+
should look for shops in an app
|
8
|
+
|
9
|
+
switch with no arguments
|
10
|
+
you get a list:
|
11
|
+
|
12
|
+
test shops:
|
13
|
+
1. cronin
|
14
|
+
|
15
|
+
apps (development):
|
16
|
+
1. metafieldseditor
|
17
|
+
2. shipping
|
18
|
+
|
19
|
+
apps (heroku):
|
20
|
+
1. metafieldseditor
|
21
|
+
2. shipping
|
22
|
+
|
23
|
+
|
24
|
+
|
25
|
+
when you choose
|
26
|
+
|
27
|
+
|
28
|
+
# To check out
|
29
|
+
|
30
|
+
https://github.com/pry/pry-coolline
|
31
|
+
https://github.com/cldwalker/bond
|
32
|
+
|
33
|
+
|
data/README.md
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
# Shopifydev
|
2
|
+
|
3
|
+
Abstract out and port to ruby the functionality of the shopify textmate bundle for use in other editors.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'shopifydev'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install shopifydev
|
18
|
+
|
19
|
+
Once Shopifydev is installed, you'll need to add a .shopifydev.yaml file to your project root. This config
|
20
|
+
file should contain the secrets specific to the shopify site you are working on. Here's a sample:
|
21
|
+
|
22
|
+
api_key: youneedakey
|
23
|
+
password: andapassword
|
24
|
+
url: my_store_url.myshopify.com
|
25
|
+
project_root: relative/path (this might just be '.' for a lot of you cats)
|
26
|
+
project_root_variable: SOME_ENVIRONMENT_VARIABLE
|
27
|
+
|
28
|
+
Don't include 'http://' in the url, and don't commit this file to your repo (because secrets). The project
|
29
|
+
root should be the directory where the 'assets' directory lives. If you would rather use an environment
|
30
|
+
variable specific to your text editor of choice, like TM_PROJECT_DIRECTORY, you can supply that as well.
|
31
|
+
Shopifydev will always prefer the environment variable, though.
|
32
|
+
|
33
|
+
## Usage
|
34
|
+
|
35
|
+
WARNING: Files will always be uploaded from `project_root/`. This is great, because it means you can keep
|
36
|
+
the shopify files separate from whatever sweet app you happen to be working on. Unfortunately, at the
|
37
|
+
moment, this means autocompletion of file names really only works if `project_root` is `'.'`. But Imma fix
|
38
|
+
that.
|
39
|
+
|
40
|
+
With shopifydev uploading a shopify file is a snap!
|
41
|
+
|
42
|
+
$ shopifydev upload assets/some_pic.jpg
|
43
|
+
|
44
|
+
Uploading two files is also a snap!
|
45
|
+
|
46
|
+
$ shopifydev upload assets/cart.png templates/cart.liquid
|
47
|
+
|
48
|
+
More files? It's a UNIX system! You know this!
|
49
|
+
|
50
|
+
$ shopifydev upload {snippets,templates}/*.liquid
|
51
|
+
|
52
|
+
But Mr Authors, what if I don't have any files to upload?
|
53
|
+
|
54
|
+
$ shopify download
|
55
|
+
|
56
|
+
What could be better than that? How about uploading all your files:
|
57
|
+
|
58
|
+
$ shopifydev upload --patchify patch_directory
|
59
|
+
|
60
|
+
(I wouldn't recommend running that with '.' or any directory that contains subdirectories shopify wouldn't recognize. I'll fix that someday too! (^o ^)//)
|
61
|
+
|
62
|
+
Oh, you don't want to upload all your files, and you're too lazy to glob?
|
63
|
+
Use `--gitify` to upload all the shopify files with changes.
|
64
|
+
|
65
|
+
$ shopifydev upload --gitify
|
66
|
+
|
67
|
+
(this uses the output of `git status --porcelain`, and it also runs `git add` on all those files so that
|
68
|
+
you won't upload a file twice unless it gets changed twice in the same commit)
|
69
|
+
|
70
|
+
One final tip: `alias upify='shopifydev upload'`
|
71
|
+
|
72
|
+
## Contributing
|
73
|
+
|
74
|
+
1. Fork it
|
75
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
76
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
77
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
78
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/bin/shopify_console
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'pry'
|
3
|
+
require 'shopifydev'
|
4
|
+
require 'shopifydev/pry/commands'
|
5
|
+
|
6
|
+
|
7
|
+
MY_OBJ = []
|
8
|
+
|
9
|
+
def bob
|
10
|
+
"yo, bob here"
|
11
|
+
end
|
12
|
+
# start a REPL session
|
13
|
+
binding.pry
|
14
|
+
|
15
|
+
puts "Thank you for using Shopify Console. Enjoy your day."
|
data/bin/shopifydev
ADDED
@@ -0,0 +1,100 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'gli'
|
3
|
+
begin # XXX: Remove this begin/rescue before distributing your app
|
4
|
+
require 'shopifydev'
|
5
|
+
rescue LoadError
|
6
|
+
STDERR.puts "In development, you need to use `bundle exec bin/todo` to run your app"
|
7
|
+
STDERR.puts "At install-time, RubyGems will make sure lib, etc. are in the load path"
|
8
|
+
STDERR.puts "Feel free to remove this message from bin/foxhole now"
|
9
|
+
exit 64
|
10
|
+
end
|
11
|
+
|
12
|
+
include GLI::App
|
13
|
+
|
14
|
+
program_desc "Upload shopify files from the command-line like a boss."
|
15
|
+
|
16
|
+
version Shopifydev::VERSION
|
17
|
+
|
18
|
+
desc 'verbose'
|
19
|
+
switch [:v, :verbose]
|
20
|
+
|
21
|
+
desc 'Download the theme from an existing shopify site'
|
22
|
+
arg_name '' # Download take no particular args
|
23
|
+
command :download do |c|
|
24
|
+
|
25
|
+
c.action do |global_options,options,args|
|
26
|
+
|
27
|
+
Shopifydev::CommandRunner.new.download(options)
|
28
|
+
|
29
|
+
# If you have any errors, just raise them
|
30
|
+
# raise "that command made no sense"
|
31
|
+
|
32
|
+
puts "download command ran"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
desc 'Upload a particular file to shopify'
|
37
|
+
arg_name 'remote key' # upload requires the remote key be specified here
|
38
|
+
command :upload do |c|
|
39
|
+
|
40
|
+
c.desc 'Upload all files from a given root'
|
41
|
+
c.default_value 'none'
|
42
|
+
c.arg_name 'patch_root'
|
43
|
+
c.flag [:p, :patchify]
|
44
|
+
|
45
|
+
c.desc 'Upload all files with changes in git'
|
46
|
+
c.default_value 'none'
|
47
|
+
c.switch [:g, :gitify]
|
48
|
+
|
49
|
+
c.action do |global_options,options,args|
|
50
|
+
gitify = options[:gitify] != 'none'
|
51
|
+
patchify = options[:patchify] != 'none'
|
52
|
+
raise "gitify and patchify are mutually exclusive" if gitify && patchify
|
53
|
+
|
54
|
+
mode = (patchify) ? 'patchify' : ''
|
55
|
+
mode = (gitify) ? 'gitify' : '' if mode.blank?
|
56
|
+
|
57
|
+
runner = Shopifydev::CommandRunner.new
|
58
|
+
|
59
|
+
case mode
|
60
|
+
when 'patchify'
|
61
|
+
puts mode
|
62
|
+
raise "patchify takes no args" if args.length > 0
|
63
|
+
|
64
|
+
runner.patchify(options[:p])
|
65
|
+
when 'gitify'
|
66
|
+
puts mode
|
67
|
+
raise "patchify takes no args" if args.length > 0
|
68
|
+
|
69
|
+
runner.gitify
|
70
|
+
else
|
71
|
+
puts mode
|
72
|
+
runner.upload(args)
|
73
|
+
end
|
74
|
+
|
75
|
+
puts "upload command ran"
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
pre do |global,command,options,args|
|
80
|
+
# Pre logic here
|
81
|
+
# Return true to proceed; false to abourt and not call the
|
82
|
+
# chosen command
|
83
|
+
# Use skips_pre before a command to skip this block
|
84
|
+
# on that command only
|
85
|
+
true
|
86
|
+
end
|
87
|
+
|
88
|
+
post do |global,command,options,args|
|
89
|
+
# Post logic here
|
90
|
+
# Use skips_post before a command to skip this
|
91
|
+
# block on that command only
|
92
|
+
end
|
93
|
+
|
94
|
+
on_error do |exception|
|
95
|
+
# Error logic here
|
96
|
+
# return false to skip default error handling
|
97
|
+
true
|
98
|
+
end
|
99
|
+
|
100
|
+
exit run(ARGV)
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'shopify_api'
|
2
|
+
require 'filemagic'
|
3
|
+
|
4
|
+
module Shopifydev
|
5
|
+
class Asset
|
6
|
+
attr_accessor :shop, :remote_key
|
7
|
+
|
8
|
+
def initialize(shop, path=ENV['TM_FILEPATH'], project_root)
|
9
|
+
puts "in asset::initialize"
|
10
|
+
@shop = shop
|
11
|
+
|
12
|
+
# Asset name should be relative to TM_PROJECT_DIRECTORY
|
13
|
+
# but if it isn't, then gsub just doesn't replace anything
|
14
|
+
# so if you know the key, you can just supply the key?
|
15
|
+
unless project_root.nil?
|
16
|
+
@remote_key = path.gsub(project_root + '/', '') # fix absolute path
|
17
|
+
@local_path = Pathname.new(project_root + '/' + @remote_key) # prepend project root
|
18
|
+
else
|
19
|
+
raise Exception, "could no determine project_root. In .shopifydev.yaml include\n project_root: relative/path"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def upload(root=nil)
|
24
|
+
# check that it's not binary
|
25
|
+
puts "in upload"
|
26
|
+
|
27
|
+
puts "creating asset for " + @remote_key
|
28
|
+
puts @remote_key
|
29
|
+
asset = ShopifyAPI::Asset.new(:key => @remote_key)
|
30
|
+
|
31
|
+
puts "filling with 1's and 0's from " + @local_path.to_path
|
32
|
+
|
33
|
+
contents = File.read(@local_path.to_path)
|
34
|
+
|
35
|
+
fm = FileMagic.new
|
36
|
+
|
37
|
+
if (fm.file(@local_path.realpath.to_path).include?('image'))
|
38
|
+
asset.attach contents
|
39
|
+
else
|
40
|
+
asset.value = contents
|
41
|
+
end
|
42
|
+
|
43
|
+
# TODO this doesn't fail spectacularly enough... I don't
|
44
|
+
# feel comfortable with that
|
45
|
+
puts "saving..."
|
46
|
+
if asset.valid?
|
47
|
+
if asset.save
|
48
|
+
puts "Success!"
|
49
|
+
else
|
50
|
+
puts "failed to save"
|
51
|
+
end
|
52
|
+
else
|
53
|
+
puts "failed to validate"
|
54
|
+
end
|
55
|
+
puts "---"
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
|
2
|
+
require "logger"
|
3
|
+
require "shopify_api"
|
4
|
+
|
5
|
+
module Shopifydev
|
6
|
+
class CommandRunner
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
@devshop = Shopifydev::Shop.new(credentials)
|
10
|
+
end
|
11
|
+
|
12
|
+
def credentials
|
13
|
+
unless @credentials
|
14
|
+
@credentials = YAML::load(
|
15
|
+
File.open('.shopifydev.yaml'))
|
16
|
+
end
|
17
|
+
|
18
|
+
@credentials
|
19
|
+
end
|
20
|
+
|
21
|
+
def upload(remote_keys)
|
22
|
+
# upload one asset or directory
|
23
|
+
raise "no shopify files were specified" if remote_keys.empty?
|
24
|
+
|
25
|
+
remote_keys.each do |remote_key|
|
26
|
+
if File.directory?(remote_key) then
|
27
|
+
self.upload_dir(remote_key)
|
28
|
+
else
|
29
|
+
@devshop.asset(remote_key).upload
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def patchify(patch_dir)
|
35
|
+
|
36
|
+
ENV['PATCHIFY_ROOT'] = patch_dir # temporarily set an environment variable
|
37
|
+
|
38
|
+
Dir.glob(File.join(ENV['PATCHIFY_ROOT'], "*/*")).reverse.each do |file|
|
39
|
+
|
40
|
+
self.upload(Array.wrap(File.join(file.split('/')[-2..-1])))
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def gitify
|
45
|
+
porcelain = `git status --porcelain`
|
46
|
+
|
47
|
+
modified = porcelain.scan(/^[ AM][M](.*)/).flatten.each {|f| f.strip!}
|
48
|
+
|
49
|
+
remote_keys = modified.delete_if do |file|
|
50
|
+
not ["assets", "snippets", "templates", "layout"].include?(file.split('/')[0].strip)
|
51
|
+
end
|
52
|
+
|
53
|
+
remote_keys.each do |file|
|
54
|
+
`git add #{file}`
|
55
|
+
end
|
56
|
+
|
57
|
+
upload(remote_keys)
|
58
|
+
end
|
59
|
+
|
60
|
+
def upload_dir(upload_dir)
|
61
|
+
# upload all assets in the given dir
|
62
|
+
|
63
|
+
Dir[upload_dir + "/*"].each do |remote_key|
|
64
|
+
self.upload(remote_key)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def upload_glob(glob)
|
69
|
+
# upload all assets in the given dir matching a given pattern
|
70
|
+
|
71
|
+
glob.each do |remote_key|
|
72
|
+
self.upload(remote_key)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def download(options={})
|
77
|
+
# Download the whole template
|
78
|
+
|
79
|
+
@devshop.template.download
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Shopifydev
|
2
|
+
module Generators
|
3
|
+
class Shop < Thor::Group
|
4
|
+
include Thor::Actions
|
5
|
+
|
6
|
+
source_root File.expand_path('../templates', __FILE__)
|
7
|
+
|
8
|
+
argument :name
|
9
|
+
class_option :test_shop
|
10
|
+
class_option :live_shop
|
11
|
+
|
12
|
+
def setup
|
13
|
+
create_file "#{name}/TODO"
|
14
|
+
copy_file "Gemfile", "#{name}/Gemfile"
|
15
|
+
copy_file "rvmrc", "#{name}/.rvmrc"
|
16
|
+
copy_file "gitignore", "#{name}/.gitignore"
|
17
|
+
copy_file "shopify-tmbundle", "#{name}/.shopify-tmbundle"
|
18
|
+
system "git init"
|
19
|
+
system "git add --all"
|
20
|
+
system 'git commit -m "initial setup"'
|
21
|
+
end
|
22
|
+
|
23
|
+
def download_template
|
24
|
+
say "TODO: automate downloading template from test shop"
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
.shopify-tmbundle
|
@@ -0,0 +1 @@
|
|
1
|
+
rvm use ruby-1.9.3-p194@shopify
|
@@ -0,0 +1,21 @@
|
|
1
|
+
; config file for shopify.tmbundle
|
2
|
+
; You can now setup multiple shops. Just follow the pattern you see below.
|
3
|
+
; You can have more than 2 (as many as you want really)
|
4
|
+
; this config uses ini style http://php.net/manual/en/function.parse-ini-file.php
|
5
|
+
; you can just change the settings under default, and everything should work.
|
6
|
+
; or you can do things the old way as well.
|
7
|
+
|
8
|
+
; this is the currently active shop. you can change it here
|
9
|
+
use="default"
|
10
|
+
|
11
|
+
; test shop for development
|
12
|
+
[default]
|
13
|
+
api_key="###TEST_SHOP_API_KEY###"
|
14
|
+
password="###TEST_SHOP_PASSWORD###"
|
15
|
+
store="TEST_SHOP_DOMAIN"
|
16
|
+
|
17
|
+
; and the live shop
|
18
|
+
[live]
|
19
|
+
api_key="###LIVE_SHOP_API_KEY###"
|
20
|
+
password="###LIVE_SHOP_PASSWORD###"
|
21
|
+
store="###LIVE_SHOP_DOMAIN###"
|