bootic_cli 0.3.0 → 0.4.0

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: 1635165613bb3c1108f62bcf3fb9a455b66a22cc
4
- data.tar.gz: b9eda84070803bdf7892769033bc5ceb4dd38b05
3
+ metadata.gz: c74b9f852a960a50c152cef0dc870ecf9e39eb46
4
+ data.tar.gz: 8badbddd5640c48465531fc40ab690fe83ebdfb3
5
5
  SHA512:
6
- metadata.gz: 2921db246029beec8a51e242a5635524a7106fc8f2d2cd93cd52b660597b4bee084ed04ef09109ee2502fce068be135a276f08d002fdbde761653d1d78fb5124
7
- data.tar.gz: 07db650fb21e51a90e1042c940ada82a8af43abdb85f6a34a183caa391153bca54c6b045f4c248abfc4e8910171b9683fecfc55965dc6ad52f60cad3d732121b
6
+ metadata.gz: 4f3a737ceaadbe4a4533fedcfaa90c98ef627aa01d5e4807a271538588608731f5bfeb354df730f242633c50d0bacc00ada01520a6a41f9b0ff274a66d942dd1
7
+ data.tar.gz: 1b5f6e3e05545c14365eaaa5c759ea209758bbec3c90e8d880bb97c94ad07eb74c6f29fb3398c362c4ee9fe42e1cfa40e8a4f4f3437356771fda28716310eea1
data/bin/bootic CHANGED
@@ -1,4 +1,4 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require "bootic_cli"
3
+ require 'bootic_cli'
4
4
  BooticCli::CLI.start
@@ -123,7 +123,7 @@ module BooticCli
123
123
  end
124
124
  end
125
125
 
126
- desc "erase", "clear all credentials from this computer"
126
+ desc 'erase', 'Clear all credentials from this computer'
127
127
  def erase
128
128
  if session.setup?
129
129
  session.erase!
@@ -208,7 +208,7 @@ module BooticCli
208
208
  end
209
209
  end
210
210
 
211
- require "bootic_cli/command"
211
+ require 'bootic_cli/command'
212
212
 
213
213
  Dir[File.join(File.dirname(__FILE__), 'commands', '*.rb')].each do |f|
214
214
  load_file f
@@ -13,46 +13,55 @@ module BooticCli
13
13
 
14
14
  desc 'clone [dir]', 'Clone remote theme into directory [dir]'
15
15
  option :shop, banner: '<shop_subdomain>', type: :string
16
- option :destroy, banner: '<true|false>', type: :boolean, default: true
17
- option :public, banner: '<true|false>', type: :boolean, default: false, aliases: '-p'
16
+ option :public, banner: '<true|false>', type: :boolean, aliases: '-p', desc: 'Clones public theme, even if dev theme exists'
17
+ option :dev, banner: '<true|false>', type: :boolean, aliases: '-d', desc: 'Clones development theme, or creates one if missing'
18
18
  def clone(dir = nil)
19
19
  logged_in_action do
20
- local_theme, remote_theme = theme_selector.setup_theme_pair(options['shop'], dir, options['public'])
21
- workflows.pull(local_theme, remote_theme, destroy: options['destroy'])
20
+ local_theme, remote_theme = theme_selector.setup_theme_pair(options['shop'], dir, options['public'], options['dev'])
21
+
22
+ if File.exist?(local_theme.path)
23
+ prompt.say "Directory already exists! (#{local_theme.path})", :red
24
+ else
25
+ prompt.say "Cloning theme files into #{local_theme.path}"
26
+ workflows.pull(local_theme, remote_theme)
27
+ local_theme.write_subdomain
28
+ end
22
29
  end
23
30
  end
24
31
 
25
32
  desc 'pull', 'Pull remote changes into current theme directory'
26
- option :public, banner: '<true|false>', type: :boolean, default: false, aliases: '-p'
27
- option :destroy, banner: '<true|false>', type: :boolean, default: true
33
+ option :public, banner: '<true|false>', type: :boolean, aliases: '-p', desc: 'Pull from public theme, even if dev theme exists'
34
+ option :delete, banner: '<true|false>', type: :boolean, desc: 'Remove local files that were removed in remote theme (default: true)'
28
35
  def pull
29
36
  within_theme do
30
37
  local_theme, remote_theme = theme_selector.select_theme_pair(default_subdomain, current_dir, options['public'])
31
- workflows.pull(local_theme, remote_theme, destroy: options['destroy'])
38
+ workflows.pull(local_theme, remote_theme, delete: options['delete'] || true)
32
39
  end
33
40
  end
34
41
 
35
42
  desc 'push', 'Push all local theme files in current dir to remote shop'
36
- option :public, banner: '<true|false>', type: :boolean, default: false, aliases: '-p'
37
- option :destroy, banner: '<true|false>', type: :boolean, default: true
43
+ option :public, banner: '<true|false>', type: :boolean, aliases: '-p', desc: 'Push to public theme, even if dev theme exists'
44
+ option :delete, banner: '<true|false>', type: :boolean, desc: 'Remove files in remote theme that were removed locally (default: true)'
38
45
  def push
39
46
  within_theme do
40
47
  local_theme, remote_theme = theme_selector.select_theme_pair(default_subdomain, current_dir, options['public'])
41
- workflows.push(local_theme, remote_theme, destroy: options['destroy'])
48
+ warn_user if remote_theme.public? and options['public'].nil?
49
+ workflows.push(local_theme, remote_theme, delete: options['delete'] || true)
42
50
  end
43
51
  end
44
52
 
45
- desc 'sync', 'Sync local theme copy in local dir with remote shop'
46
- option :public, banner: '<true|false>', type: :boolean, default: false, aliases: '-p'
53
+ desc 'sync', 'Sync changes from local theme copy with remote'
54
+ option :public, banner: '<true|false>', type: :boolean, aliases: '-p', desc: 'Sync to public theme, even if dev theme exists'
47
55
  def sync
48
56
  within_theme do
49
57
  local_theme, remote_theme = theme_selector.select_theme_pair(default_subdomain, current_dir, options['public'])
58
+ warn_user if remote_theme.public? and options['public'].nil?
50
59
  workflows.sync(local_theme, remote_theme)
51
60
  end
52
61
  end
53
62
 
54
63
  desc 'compare', 'Show differences between local and remote copies'
55
- option :public, banner: '<true|false>', type: :boolean, default: false, aliases: '-p'
64
+ option :public, banner: '<true|false>', type: :boolean, aliases: '-p', desc: 'Compare against public theme, even if dev theme exists'
56
65
  def compare
57
66
  within_theme do
58
67
  local_theme, remote_theme = theme_selector.select_theme_pair(default_subdomain, current_dir, options['public'])
@@ -60,11 +69,12 @@ module BooticCli
60
69
  end
61
70
  end
62
71
 
63
- desc 'watch', 'Watch local theme directory and create/update/delete remote one when any file changes'
64
- option :public, banner: '<true|false>', type: :boolean, default: false, aliases: '-p'
72
+ desc 'watch', 'Watch local theme dir and update remote when any file changes'
73
+ option :public, banner: '<true|false>', type: :boolean, aliases: '-p', desc: 'Pushes any changes to public theme, even if dev theme exists'
65
74
  def watch
66
75
  within_theme do
67
76
  _, remote_theme = theme_selector.select_theme_pair(default_subdomain, current_dir, options['public'])
77
+ warn_user if remote_theme.public? and options['public'].nil?
68
78
  workflows.watch(current_dir, remote_theme)
69
79
  end
70
80
  end
@@ -78,7 +88,7 @@ module BooticCli
78
88
  end
79
89
 
80
90
  desc 'open', 'Open theme preview URL in a browser'
81
- option :public, banner: '<true|false>', type: :boolean, default: false, aliases: '-p'
91
+ option :public, banner: '<true|false>', type: :boolean, aliases: '-p', desc: 'Opens public theme URL'
82
92
  def open
83
93
  within_theme do
84
94
  _, remote_theme = theme_selector.select_theme_pair(default_subdomain, current_dir, options['public'])
@@ -97,9 +107,15 @@ module BooticCli
97
107
 
98
108
  private
99
109
 
110
+ def warn_user
111
+ unless prompt.yes_or_no?("You're pushing changes directly to your public theme. Are you sure?", true)
112
+ prompt.say("Ok, sure. You can skip the above warning prompt by passing a `--public` flag.")
113
+ abort
114
+ end
115
+ end
116
+
100
117
  def within_theme(&block)
101
- dir = File.expand_path(current_dir)
102
- unless File.exist?(File.join(dir, 'layout.html'))
118
+ unless is_within_theme?
103
119
  prompt.say "This directory doesn't look like a Bootic theme! (#{dir})", :magenta
104
120
  abort
105
121
  end
@@ -109,6 +125,11 @@ module BooticCli
109
125
  end
110
126
  end
111
127
 
128
+ def is_within_theme?
129
+ dir = File.expand_path(current_dir)
130
+ File.exist?(File.join(dir, 'layout.html'))
131
+ end
132
+
112
133
  def current_dir
113
134
  '.'
114
135
  end
@@ -136,7 +157,14 @@ module BooticCli
136
157
 
137
158
  def yes_or_no?(question, default_answer)
138
159
  default_char = default_answer ? 'y' : 'n'
139
- input = shell.ask("#{question} [#{default_char}]").strip
160
+
161
+ begin
162
+ input = shell.ask("#{question} [#{default_char}]").strip
163
+ rescue Interrupt
164
+ say "\nCtrl-C received. Bailing out!", :red
165
+ abort
166
+ end
167
+
140
168
  return default_answer if input == '' || input.downcase == default_char
141
169
  !default_answer
142
170
  end
@@ -24,6 +24,14 @@ module BooticCli
24
24
  end
25
25
 
26
26
  # this is unique to API themes
27
+ def public?
28
+ !dev?
29
+ end
30
+
31
+ def dev?
32
+ theme.can?(:publish_theme)
33
+ end
34
+
27
35
  def publish(clone = false)
28
36
  if theme.can?(:publish_theme)
29
37
  @theme = theme.publish_theme
@@ -31,12 +31,20 @@ module BooticCli
31
31
  [item, type]
32
32
  end
33
33
 
34
- attr_reader :subdomain
35
-
36
34
  def initialize(dir, subdomain: nil)
37
35
  @dir = dir
38
36
  @setup = false
39
- @subdomain = subdomain ? write_subdomain(subdomain) : read_subdomain
37
+ @subdomain = subdomain
38
+ end
39
+
40
+ def subdomain
41
+ @subdomain || read_subdomain
42
+ end
43
+
44
+ def write_subdomain
45
+ store.transaction do
46
+ store['subdomain'] = @subdomain
47
+ end
40
48
  end
41
49
 
42
50
  def reset!
@@ -132,15 +140,8 @@ module BooticCli
132
140
  )
133
141
  end
134
142
 
135
- def write_subdomain(sub)
136
- store.transaction do
137
- store['subdomain'] = sub
138
- end
139
- sub
140
- end
141
-
142
143
  def read_subdomain
143
- store.transaction{ store['subdomain'] }
144
+ store.transaction { store['subdomain'] }
144
145
  end
145
146
  end
146
147
  end
@@ -11,6 +11,14 @@ module BooticCli
11
11
  # Implement generic Theme interface
12
12
  attr_reader :templates, :assets
13
13
 
14
+ def public?
15
+ false # just for tests
16
+ end
17
+
18
+ def path
19
+ nil
20
+ end
21
+
14
22
  def reload!
15
23
  @templates = []
16
24
  @assets = []
@@ -9,16 +9,27 @@ module BooticCli
9
9
  @prompt = prompt
10
10
  end
11
11
 
12
- def setup_theme_pair(subdomain, dir = nil, production = false)
12
+ def setup_theme_pair(subdomain, dir = nil, wants_public = false, wants_dev = false)
13
+ raise "Cannot pass both public and dev flags at the same time!" if wants_public && wants_dev
14
+
13
15
  shop = find_remote_shop(subdomain)
14
16
  raise "No shop with subdomain #{subdomain}" unless shop
15
17
 
16
18
  path = dir || shop.subdomain
17
- local_theme = select_local_theme(path, shop.subdomain)
18
- remote_theme = select_remote_theme(shop, production)
19
+ local_theme = select_local_theme(path, shop.subdomain)
20
+ remote_theme = select_remote_theme(shop, wants_public)
21
+
22
+ # if no `wants_public` flag was passed and no dev theme is present
23
+ # ask the user whether he/she wants to create one now.
24
+ if !wants_public and remote_theme.public?
25
+ raise 'Dev theme not available!' unless shop.themes.can?(:create_dev_theme)
26
+
27
+ if wants_dev or prompt.yes_or_no?("Would you like to create (and work on) a development version of your theme? (recommended)", true)
28
+ prompt.say "Good thinking. Creating a development theme out of your current public one...", :green
29
+ remote_theme = shop.themes.create_dev_theme
30
+ end
31
+ end
19
32
 
20
- prompt.say "Cloning theme files into #{local_theme.path}"
21
- prompt.say "Preview this theme at #{remote_theme.path}", :magenta
22
33
  [local_theme, remote_theme]
23
34
  end
24
35
 
@@ -27,15 +38,15 @@ module BooticCli
27
38
  shop = find_remote_shop(local_theme.subdomain)
28
39
  raise "No shop with subdomain #{local_theme.subdomain}" unless shop
29
40
  remote_theme = select_remote_theme(shop, production)
30
-
31
- prompt.say "Preview this theme at #{remote_theme.path}", :magenta
32
41
  [local_theme, remote_theme]
33
42
  end
34
43
 
35
44
  def pair(subdomain, dir)
36
45
  shop = find_remote_shop(subdomain)
37
46
  raise "No shop with subdomain #{subdomain}" unless shop
38
- select_local_theme(dir, subdomain)
47
+ theme = select_local_theme(dir, subdomain)
48
+ theme.write_subdomain
49
+ theme
39
50
  end
40
51
 
41
52
  def select_local_theme(dir, subdomain = nil)
@@ -62,24 +73,15 @@ module BooticCli
62
73
  private
63
74
 
64
75
  def resolve_remote_theme(shop, production = false)
65
- if production
66
- prompt.say "Working on public theme of shop #{shop.subdomain}", :red
67
- return shop.theme
68
- end
69
-
70
- prompt.say "Working on development theme of shop #{shop.subdomain}", :green
71
- themes = shop.themes
72
- if themes.has?(:dev_theme)
73
- themes.dev_theme
74
- elsif themes.can?(:create_dev_theme)
75
- prompt.say "Creating development theme...", :green
76
- themes.create_dev_theme
76
+ if production or !shop.themes.has?(:dev_theme)
77
+ prompt.say "Working on public theme of shop #{shop.subdomain}", :yellow
78
+ shop.theme
77
79
  else
78
- raise "No dev theme available"
80
+ prompt.say "Working on development theme of shop #{shop.subdomain}", :green
81
+ shop.themes.dev_theme
79
82
  end
80
83
  end
81
84
 
82
- private
83
85
  attr_reader :root, :prompt
84
86
  end
85
87
  end
@@ -31,7 +31,7 @@ module BooticCli
31
31
  @prompt = prompt
32
32
  end
33
33
 
34
- def pull(local_theme, remote_theme, destroy: true)
34
+ def pull(local_theme, remote_theme, delete: true)
35
35
  diff = ThemeDiff.new(source: local_theme, target: remote_theme)
36
36
  check_dupes!(local_theme.assets)
37
37
 
@@ -45,7 +45,7 @@ module BooticCli
45
45
  local_theme.add_template t.file_name, t.body
46
46
  end
47
47
 
48
- if destroy
48
+ if delete
49
49
  notice 'Removing local files that were removed on remote...'
50
50
  remove_all(diff.missing_in_target, local_theme)
51
51
  else
@@ -56,9 +56,11 @@ module BooticCli
56
56
  copy_templates(diff.missing_in_source, local_theme, download_opts)
57
57
  # lets copy all of them and let user decide to overwrite existing
58
58
  copy_assets(remote_theme, local_theme, download_opts)
59
+
60
+ prompt.say "Done! Preview this theme at #{remote_theme.path}", :cyan
59
61
  end
60
62
 
61
- def push(local_theme, remote_theme, destroy: true)
63
+ def push(local_theme, remote_theme, delete: true)
62
64
  diff = ThemeDiff.new(source: local_theme, target: remote_theme)
63
65
  check_dupes!(local_theme.assets)
64
66
 
@@ -74,12 +76,14 @@ module BooticCli
74
76
  copy_assets(diff.missing_in_target, remote_theme, overwrite: true)
75
77
  copy_templates(diff.missing_in_target, remote_theme)
76
78
 
77
- if destroy
79
+ if delete
78
80
  notice 'Removing remote files that were removed locally...'
79
81
  remove_all(diff.missing_in_source, remote_theme)
80
82
  else
81
83
  notice 'Not removing remote files that were removed locally.'
82
84
  end
85
+
86
+ prompt.say "Done! View updated version at #{remote_theme.path}", :cyan
83
87
  end
84
88
 
85
89
  def sync(local_theme, remote_theme)
@@ -112,6 +116,8 @@ module BooticCli
112
116
  notice 'Uploading missing remote templates & assets...'
113
117
  copy_templates(diff.missing_in_target, remote_theme, download_opts)
114
118
  copy_assets(diff.missing_in_target, remote_theme, overwrite: true)
119
+
120
+ prompt.say "Synced! Preview this theme at #{remote_theme.path}", :cyan
115
121
  end
116
122
 
117
123
  def compare(local_theme, remote_theme)
@@ -181,6 +187,7 @@ module BooticCli
181
187
  exit
182
188
  }
183
189
 
190
+ prompt.say "Preview changes at #{remote_theme.path}", :cyan
184
191
  Kernel.sleep
185
192
  end
186
193
 
@@ -188,7 +195,7 @@ module BooticCli
188
195
  keep_old_theme = prompt.yes_or_no?("Do you want to keep your old public theme as your dev theme?", false)
189
196
  # first push local files to dev theme
190
197
  prompt.say "Pushing local changes to development theme"
191
- push local_theme, remote_theme, destroy: true
198
+ push(local_theme, remote_theme, delete: true)
192
199
  # now publish remote dev theme
193
200
  # let it fail if remote_theme doesn't respond to #publish
194
201
  prompt.notice "Publishing development theme"
@@ -1,3 +1,3 @@
1
1
  module BooticCli
2
- VERSION = "0.3.0"
2
+ VERSION = "0.4.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bootic_cli
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ismael Celis
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-01-23 00:00:00.000000000 Z
11
+ date: 2018-01-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor