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.
Files changed (42) hide show
  1. data/.gitignore +17 -0
  2. data/.pryrc +3 -0
  3. data/.root.shopifydev.yaml.sample +21 -0
  4. data/.ruby-version +1 -0
  5. data/.shopifydev.yaml.sample +7 -0
  6. data/Gemfile +4 -0
  7. data/LICENSE.txt +22 -0
  8. data/NEXTSTEPS.md +33 -0
  9. data/README.md +78 -0
  10. data/Rakefile +1 -0
  11. data/bin/shopify_console +15 -0
  12. data/bin/shopifydev +100 -0
  13. data/lib/rails/generators/shopifydev/shops_generator.rb +11 -0
  14. data/lib/rails/generators/shopifydev/templates/shops.rake +5 -0
  15. data/lib/rails/tasks/shops.rake +7 -0
  16. data/lib/shopifydev/asset.rb +58 -0
  17. data/lib/shopifydev/commands.rb +83 -0
  18. data/lib/shopifydev/config.rb +9 -0
  19. data/lib/shopifydev/generators/shop.rb +29 -0
  20. data/lib/shopifydev/generators/templates/Gemfile +10 -0
  21. data/lib/shopifydev/generators/templates/gitignore +1 -0
  22. data/lib/shopifydev/generators/templates/rvmrc +1 -0
  23. data/lib/shopifydev/generators/templates/shopify-tmbundle +21 -0
  24. data/lib/shopifydev/pry/commands.rb +194 -0
  25. data/lib/shopifydev/railtie.rb +11 -0
  26. data/lib/shopifydev/shop.rb +38 -0
  27. data/lib/shopifydev/template.rb +73 -0
  28. data/lib/shopifydev/version.rb +3 -0
  29. data/lib/shopifydev.rb +10 -0
  30. data/shopifydev.gemspec +35 -0
  31. data/spec/shopifydev/config_spec.rb +5 -0
  32. data/spec/shopifydev/generators/shopifydev/shopifydev_generator_spec.rb +5 -0
  33. data/spec/shopifydev/pry/commands_spec.rb +5 -0
  34. data/spec/shopifydev/railtie_spec.rb +5 -0
  35. data/templates/customers/order.liquid +109 -0
  36. data/templates/customers/register.liquid +42 -0
  37. data/templates/page.support.liquid +78 -0
  38. data/templates/page.verbose.liquid +18 -0
  39. data/templates/product.liquid +284 -0
  40. data/templates/search.liquid +63 -0
  41. data/test_driver.rb +31 -0
  42. metadata +275 -0
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/.pryrc ADDED
@@ -0,0 +1,3 @@
1
+ require 'bundler/setup'
2
+ require 'shopifydev'
3
+ require 'shopifydev/pry/commands'
@@ -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
@@ -0,0 +1,7 @@
1
+ # rename this to .shopifydev.yaml and don't add live secrets here
2
+ ---
3
+ api_key: youneedakey
4
+ password: andapassword
5
+ url: my_store_url.myshopify.com/
6
+ project_root: relative/path
7
+ project_root_variable: SOME_ENVIRONMENT_VARIABLE
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in shopifydev.gemspec
4
+ gemspec
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"
@@ -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,11 @@
1
+ require 'rails/generators/base'
2
+
3
+ module Shopifydev
4
+ class ShopsGenerator < Rails::Generators::Base
5
+ source_root File.expand_path('../templates', __FILE__)
6
+
7
+ def rake_task
8
+ copy_file "shops.rake", "lib/tasks/shops.rake"
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,5 @@
1
+ desc "Outputs list of shops that have installed the app"
2
+ task :shops => :environment do
3
+ url_column = Shop.column_names.detect{|c| c =~ /url|domain/}
4
+ puts Shop.select("id,#{url_column},token").all.to_json
5
+ end
@@ -0,0 +1,7 @@
1
+ desc "Outputs list of shops that have installed the app"
2
+ task :shops => :environment do
3
+ url_column = Shop.column_names.detect{|c| c =~ /url|domain/}
4
+ json = Shop.select("id,#{url_column},token").all.to_json
5
+ puts "----snip----"
6
+ puts json
7
+ end
@@ -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,9 @@
1
+ require 'active_support/core_ext/hash'
2
+
3
+ module Shopifydev
4
+ module Config
5
+ def self.config
6
+ YAML::load(File.open(File.expand_path('~/.shopifydev.yaml'))).with_indifferent_access
7
+ end
8
+ end
9
+ 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,10 @@
1
+ source "http://rubygems.org"
2
+
3
+ gem "mechanize"
4
+ gem 'watchr'
5
+ gem 'thor'
6
+ gem 'shopify_api'
7
+ gem "shopify-api-limits"
8
+ gem 'guard'
9
+ gem 'activesupport'
10
+ gem 'inifile'
@@ -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###"