shopify-cli 1.5.0 → 1.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/PULL_REQUEST_TEMPLATE.md +1 -0
- data/.travis.yml +1 -0
- data/CHANGELOG.md +9 -0
- data/README.md +39 -7
- data/Rakefile +2 -0
- data/dev.yml +2 -2
- data/docs/_config.yml +1 -18
- data/docs/app/node/commands/index.md +2 -80
- data/docs/app/node/index.md +2 -33
- data/docs/app/rails/commands/index.md +2 -78
- data/docs/app/rails/index.md +2 -34
- data/docs/core/index.md +2 -84
- data/docs/getting-started/index.md +2 -25
- data/docs/getting-started/install/index.md +1 -118
- data/docs/getting-started/migrate/index.md +2 -94
- data/docs/getting-started/uninstall/index.md +2 -35
- data/docs/getting-started/upgrade/index.md +2 -39
- data/docs/help/start-app/index.md +2 -4
- data/docs/index.md +2 -24
- data/install.sh +1 -1
- data/lib/project_types/extension/cli.rb +19 -10
- data/lib/project_types/extension/commands/extension_command.rb +2 -2
- data/lib/project_types/extension/features/argo.rb +117 -0
- data/lib/project_types/extension/forms/create.rb +2 -2
- data/lib/project_types/extension/models/specification.rb +35 -0
- data/lib/project_types/extension/models/specification_handlers/checkout_post_purchase.rb +19 -0
- data/lib/project_types/extension/models/specification_handlers/default.rb +67 -0
- data/lib/project_types/extension/models/specifications.rb +77 -0
- data/lib/project_types/extension/tasks/configure_features.rb +52 -0
- data/lib/project_types/extension/tasks/fetch_specifications.rb +38 -0
- data/lib/project_types/node/commands/create.rb +3 -1
- data/lib/project_types/node/commands/generate.rb +2 -11
- data/lib/project_types/node/messages/messages.rb +9 -44
- data/lib/project_types/rails/commands/create.rb +8 -9
- data/lib/project_types/rails/forms/create.rb +1 -1
- data/lib/project_types/rails/gem.rb +1 -1
- data/lib/project_types/rails/messages/messages.rb +1 -1
- data/lib/project_types/script/cli.rb +7 -4
- data/lib/project_types/script/commands/create.rb +6 -4
- data/lib/project_types/script/commands/push.rb +5 -13
- data/lib/project_types/script/config/extension_points.yml +9 -5
- data/lib/project_types/script/errors.rb +17 -0
- data/lib/project_types/script/forms/create.rb +26 -2
- data/lib/project_types/script/graphql/app_script_update_or_create.graphql +10 -1
- data/lib/project_types/script/layers/application/build_script.rb +9 -4
- data/lib/project_types/script/layers/application/create_script.rb +12 -10
- data/lib/project_types/script/layers/application/extension_points.rb +24 -0
- data/lib/project_types/script/layers/application/push_script.rb +18 -16
- data/lib/project_types/script/layers/domain/errors.rb +4 -0
- data/lib/project_types/script/layers/domain/extension_point.rb +62 -6
- data/lib/project_types/script/layers/domain/metadata.rb +55 -0
- data/lib/project_types/script/layers/domain/push_package.rb +25 -6
- data/lib/project_types/script/layers/infrastructure/assemblyscript_project_creator.rb +6 -6
- data/lib/project_types/script/layers/infrastructure/assemblyscript_task_runner.rb +16 -6
- data/lib/project_types/script/layers/infrastructure/extension_point_repository.rb +10 -4
- data/lib/project_types/script/layers/infrastructure/project_creator.rb +2 -1
- data/lib/project_types/script/layers/infrastructure/push_package_repository.rb +25 -13
- data/lib/project_types/script/layers/infrastructure/rust_project_creator.rb +72 -0
- data/lib/project_types/script/layers/infrastructure/rust_task_runner.rb +59 -0
- data/lib/project_types/script/layers/infrastructure/script_service.rb +7 -1
- data/lib/project_types/script/layers/infrastructure/task_runner.rb +4 -3
- data/lib/project_types/script/messages/messages.rb +39 -8
- data/lib/project_types/script/script_project.rb +25 -16
- data/lib/project_types/script/ui/error_handler.rb +34 -1
- data/lib/project_types/theme/cli.rb +40 -0
- data/lib/project_types/theme/commands/connect.rb +54 -0
- data/lib/project_types/theme/commands/create.rb +48 -0
- data/lib/project_types/theme/commands/deploy.rb +38 -0
- data/lib/project_types/theme/commands/generate.rb +20 -0
- data/lib/project_types/theme/commands/generate/env.rb +79 -0
- data/lib/project_types/theme/commands/push.rb +55 -0
- data/lib/project_types/theme/commands/serve.rb +31 -0
- data/lib/project_types/theme/forms/connect.rb +34 -0
- data/lib/project_types/theme/forms/create.rb +22 -0
- data/lib/project_types/theme/messages/messages.rb +147 -0
- data/lib/project_types/theme/tasks/ensure_themekit_installed.rb +78 -0
- data/lib/project_types/theme/themekit.rb +113 -0
- data/lib/shopify-cli/admin_api.rb +42 -2
- data/lib/shopify-cli/api.rb +27 -24
- data/lib/shopify-cli/commands/system.rb +1 -1
- data/lib/shopify-cli/context.rb +23 -2
- data/lib/shopify-cli/feature.rb +0 -2
- data/lib/shopify-cli/http_request.rb +20 -8
- data/lib/shopify-cli/messages/messages.rb +6 -3
- data/lib/shopify-cli/method_object.rb +104 -0
- data/lib/shopify-cli/partners_api.rb +8 -2
- data/lib/shopify-cli/project_type.rb +1 -1
- data/lib/shopify-cli/resolve_constant.rb +25 -0
- data/lib/shopify-cli/result.rb +432 -0
- data/lib/shopify-cli/shopifolk.rb +3 -2
- data/lib/shopify-cli/tasks/select_org_and_shop.rb +6 -5
- data/lib/shopify-cli/tunnel.rb +7 -1
- data/lib/shopify-cli/version.rb +1 -1
- data/lib/shopify_cli.rb +4 -1
- data/shopify.fish +1 -1
- data/shopify.sh +1 -1
- data/vendor/deps/cli-kit/REVISION +1 -1
- data/vendor/deps/cli-kit/lib/cli/kit/logger.rb +2 -2
- data/vendor/deps/cli-kit/lib/cli/kit/system.rb +3 -3
- data/vendor/deps/cli-ui/REVISION +1 -1
- data/vendor/deps/cli-ui/lib/cli/ui.rb +26 -22
- data/vendor/deps/cli-ui/lib/cli/ui/ansi.rb +4 -6
- data/vendor/deps/cli-ui/lib/cli/ui/frame.rb +3 -3
- data/vendor/deps/cli-ui/lib/cli/ui/frame/frame_stack.rb +8 -9
- data/vendor/deps/cli-ui/lib/cli/ui/frame/frame_style.rb +1 -1
- data/vendor/deps/cli-ui/lib/cli/ui/glyph.rb +1 -0
- data/vendor/deps/cli-ui/lib/cli/ui/printer.rb +15 -3
- data/vendor/deps/cli-ui/lib/cli/ui/prompt/interactive_options.rb +4 -11
- data/vendor/deps/cli-ui/lib/cli/ui/spinner.rb +3 -5
- data/vendor/deps/cli-ui/lib/cli/ui/terminal.rb +10 -10
- data/vendor/deps/cli-ui/lib/cli/ui/version.rb +1 -1
- data/vendor/deps/cli-ui/lib/cli/ui/wrap.rb +56 -0
- data/vendor/deps/webrick/.gitignore +9 -0
- data/vendor/deps/webrick/Gemfile +3 -0
- data/vendor/deps/webrick/LICENSE.txt +22 -0
- data/vendor/deps/webrick/README.md +61 -0
- data/vendor/deps/webrick/Rakefile +10 -0
- data/vendor/deps/webrick/lib/webrick.rb +232 -0
- data/vendor/deps/webrick/lib/webrick/accesslog.rb +157 -0
- data/vendor/deps/webrick/lib/webrick/cgi.rb +313 -0
- data/vendor/deps/webrick/lib/webrick/compat.rb +36 -0
- data/vendor/deps/webrick/lib/webrick/config.rb +158 -0
- data/vendor/deps/webrick/lib/webrick/cookie.rb +172 -0
- data/vendor/deps/webrick/lib/webrick/htmlutils.rb +30 -0
- data/vendor/deps/webrick/lib/webrick/httpauth.rb +96 -0
- data/vendor/deps/webrick/lib/webrick/httpauth/authenticator.rb +117 -0
- data/vendor/deps/webrick/lib/webrick/httpauth/basicauth.rb +116 -0
- data/vendor/deps/webrick/lib/webrick/httpauth/digestauth.rb +395 -0
- data/vendor/deps/webrick/lib/webrick/httpauth/htdigest.rb +132 -0
- data/vendor/deps/webrick/lib/webrick/httpauth/htgroup.rb +97 -0
- data/vendor/deps/webrick/lib/webrick/httpauth/htpasswd.rb +158 -0
- data/vendor/deps/webrick/lib/webrick/httpauth/userdb.rb +53 -0
- data/vendor/deps/webrick/lib/webrick/httpproxy.rb +354 -0
- data/vendor/deps/webrick/lib/webrick/httprequest.rb +636 -0
- data/vendor/deps/webrick/lib/webrick/httpresponse.rb +564 -0
- data/vendor/deps/webrick/lib/webrick/https.rb +152 -0
- data/vendor/deps/webrick/lib/webrick/httpserver.rb +294 -0
- data/vendor/deps/webrick/lib/webrick/httpservlet.rb +23 -0
- data/vendor/deps/webrick/lib/webrick/httpservlet/abstract.rb +152 -0
- data/vendor/deps/webrick/lib/webrick/httpservlet/cgi_runner.rb +47 -0
- data/vendor/deps/webrick/lib/webrick/httpservlet/cgihandler.rb +126 -0
- data/vendor/deps/webrick/lib/webrick/httpservlet/erbhandler.rb +88 -0
- data/vendor/deps/webrick/lib/webrick/httpservlet/filehandler.rb +552 -0
- data/vendor/deps/webrick/lib/webrick/httpservlet/prochandler.rb +47 -0
- data/vendor/deps/webrick/lib/webrick/httpstatus.rb +194 -0
- data/vendor/deps/webrick/lib/webrick/httputils.rb +512 -0
- data/vendor/deps/webrick/lib/webrick/httpversion.rb +76 -0
- data/vendor/deps/webrick/lib/webrick/log.rb +156 -0
- data/vendor/deps/webrick/lib/webrick/server.rb +381 -0
- data/vendor/deps/webrick/lib/webrick/ssl.rb +215 -0
- data/vendor/deps/webrick/lib/webrick/utils.rb +265 -0
- data/vendor/deps/webrick/lib/webrick/version.rb +18 -0
- data/vendor/deps/webrick/webrick.gemspec +74 -0
- metadata +70 -26
- data/docs/Gemfile +0 -5
- data/docs/Gemfile.lock +0 -258
- data/docs/_data/nav.yml +0 -35
- data/docs/_includes/footer.html +0 -15
- data/docs/_includes/head.html +0 -19
- data/docs/_includes/sidebar_nav.html +0 -22
- data/docs/_includes/toc.html +0 -112
- data/docs/_layouts/default.html +0 -79
- data/docs/css/docs.css +0 -157
- data/docs/images/header.png +0 -0
- data/docs/installing-ruby.md +0 -28
- data/lib/project_types/extension/features/argo/admin.rb +0 -20
- data/lib/project_types/extension/features/argo/base.rb +0 -129
- data/lib/project_types/extension/features/argo/checkout.rb +0 -20
- data/lib/project_types/extension/models/type.rb +0 -81
- data/lib/project_types/extension/models/types/checkout_post_purchase.rb +0 -23
- data/lib/project_types/extension/models/types/product_subscription.rb +0 -24
- data/lib/project_types/node/commands/generate/billing.rb +0 -39
- data/lib/project_types/node/commands/generate/page.rb +0 -59
- data/lib/project_types/node/commands/generate/webhook.rb +0 -37
- data/lib/project_types/script/layers/domain/script.rb +0 -18
- data/lib/project_types/script/layers/infrastructure/script_repository.rb +0 -47
- data/lib/project_types/script/templates/ts/as-pect.config.js +0 -27
- data/lib/project_types/script/templates/ts/as-pect.d.ts +0 -1
@@ -0,0 +1,54 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module Theme
|
3
|
+
module Commands
|
4
|
+
class Connect < ShopifyCli::SubCommand
|
5
|
+
prerequisite_task :ensure_themekit_installed
|
6
|
+
|
7
|
+
options do |parser, flags|
|
8
|
+
parser.on('--store=STORE') { |url| flags[:store] = url }
|
9
|
+
parser.on('--password=PASSWORD') { |p| flags[:password] = p }
|
10
|
+
parser.on('--themeid=THEME_ID') { |id| flags[:themeid] = id }
|
11
|
+
parser.on('--env=ENV') { |env| flags[:env] = env }
|
12
|
+
end
|
13
|
+
|
14
|
+
def call(args, _name)
|
15
|
+
if ShopifyCli::Project.has_current?
|
16
|
+
@ctx.abort(@ctx.message('theme.connect.inside_project'))
|
17
|
+
end
|
18
|
+
|
19
|
+
form = Forms::Connect.ask(@ctx, args, options.flags)
|
20
|
+
return @ctx.puts(self.class.help) if form.nil?
|
21
|
+
|
22
|
+
build(form.store, form.password, form.themeid, form.name, form.env)
|
23
|
+
ShopifyCli::Project.write(@ctx,
|
24
|
+
project_type: 'theme',
|
25
|
+
organization_id: nil)
|
26
|
+
|
27
|
+
@ctx.done(@ctx.message('theme.connect.connected', form.name, form.store, @ctx.root))
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.help
|
31
|
+
ShopifyCli::Context.message('theme.connect.help', ShopifyCli::TOOL_NAME, ShopifyCli::TOOL_NAME)
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def build(store, password, themeid, name, env)
|
37
|
+
if @ctx.dir_exist?(name)
|
38
|
+
@ctx.abort(@ctx.message('theme.connect.duplicate'))
|
39
|
+
end
|
40
|
+
|
41
|
+
@ctx.mkdir_p(name)
|
42
|
+
@ctx.chdir(name)
|
43
|
+
|
44
|
+
CLI::UI::Frame.open(@ctx.message('theme.connect.connect')) do
|
45
|
+
unless Themekit.connect(@ctx, store: store, password: password, themeid: themeid, env: env)
|
46
|
+
@ctx.chdir('..')
|
47
|
+
@ctx.rm_rf(name)
|
48
|
+
@ctx.abort(@ctx.message('theme.connect.failed'))
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module Theme
|
3
|
+
module Commands
|
4
|
+
class Create < ShopifyCli::SubCommand
|
5
|
+
prerequisite_task :ensure_themekit_installed
|
6
|
+
|
7
|
+
options do |parser, flags|
|
8
|
+
parser.on('--name=NAME') { |t| flags[:title] = t }
|
9
|
+
parser.on('--password=PASSWORD') { |p| flags[:password] = p }
|
10
|
+
parser.on('--store=STORE') { |url| flags[:store] = url }
|
11
|
+
parser.on('--env=ENV') { |env| flags[:env] = env }
|
12
|
+
end
|
13
|
+
|
14
|
+
def call(args, _name)
|
15
|
+
form = Forms::Create.ask(@ctx, args, options.flags)
|
16
|
+
return @ctx.puts(self.class.help) if form.nil?
|
17
|
+
|
18
|
+
build(form.name, form.password, form.store, form.env)
|
19
|
+
ShopifyCli::Project.write(@ctx,
|
20
|
+
project_type: 'theme',
|
21
|
+
organization_id: nil) # private apps are different
|
22
|
+
|
23
|
+
@ctx.done(@ctx.message('theme.create.info.created', form.name, form.store, @ctx.root))
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.help
|
27
|
+
ShopifyCli::Context.message('theme.create.help', ShopifyCli::TOOL_NAME, ShopifyCli::TOOL_NAME)
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def build(name, password, store, env)
|
33
|
+
@ctx.abort(@ctx.message('theme.create.duplicate_theme')) if @ctx.dir_exist?(name)
|
34
|
+
|
35
|
+
@ctx.mkdir_p(name)
|
36
|
+
@ctx.chdir(name)
|
37
|
+
|
38
|
+
CLI::UI::Frame.open(@ctx.message('theme.create.creating_theme', name)) do
|
39
|
+
unless Themekit.create(@ctx, name: name, password: password, store: store, env: env)
|
40
|
+
@ctx.chdir('..')
|
41
|
+
@ctx.rm_rf(name)
|
42
|
+
@ctx.abort(@ctx.message('theme.create.failed'))
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module Theme
|
3
|
+
module Commands
|
4
|
+
class Deploy < ShopifyCli::Command
|
5
|
+
prerequisite_task :ensure_themekit_installed
|
6
|
+
|
7
|
+
options do |parser, flags|
|
8
|
+
parser.on('--env=ENV') { |env| flags[:env] = env }
|
9
|
+
parser.on('--allow-live') { flags['allow_live'] = true }
|
10
|
+
end
|
11
|
+
|
12
|
+
def call(*)
|
13
|
+
CLI::UI::Frame.open(@ctx.message('theme.deploy.deploying')) do
|
14
|
+
unless CLI::UI::Prompt.confirm(@ctx.message('theme.deploy.confirmation'))
|
15
|
+
@ctx.abort(@ctx.message('theme.deploy.abort'))
|
16
|
+
end
|
17
|
+
|
18
|
+
if options.flags[:env]
|
19
|
+
env = options.flags[:env]
|
20
|
+
options.flags.delete(:env)
|
21
|
+
end
|
22
|
+
|
23
|
+
flags = Themekit.add_flags(options.flags)
|
24
|
+
|
25
|
+
unless Themekit.deploy(@ctx, flags: flags, env: env)
|
26
|
+
@ctx.abort(@ctx.message('theme.deploy.error'))
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
@ctx.done(@ctx.message('theme.deploy.info.deployed'))
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.help
|
34
|
+
ShopifyCli::Context.message('theme.deploy.help', ShopifyCli::TOOL_NAME, ShopifyCli::TOOL_NAME)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'shopify_cli'
|
3
|
+
|
4
|
+
module Theme
|
5
|
+
module Commands
|
6
|
+
class Generate < ShopifyCli::Command
|
7
|
+
prerequisite_task :ensure_themekit_installed
|
8
|
+
|
9
|
+
subcommand :Env, 'env', Project.project_filepath('commands/generate/env')
|
10
|
+
|
11
|
+
def call(*)
|
12
|
+
@ctx.puts(self.class.help)
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.help
|
16
|
+
ShopifyCli::Context.message('theme.generate.help', ShopifyCli::TOOL_NAME)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
module Theme
|
2
|
+
module Commands
|
3
|
+
class Generate
|
4
|
+
class Env < ShopifyCli::SubCommand
|
5
|
+
options do |parser, flags|
|
6
|
+
parser.on('--store=STORE') { |url| flags[:store] = url }
|
7
|
+
parser.on('--password=PASSWORD') { |p| flags[:password] = p }
|
8
|
+
parser.on('--themeid=THEME_ID') { |id| flags[:themeid] = id }
|
9
|
+
parser.on('--env=ENV') { |env| flags[:env] = env }
|
10
|
+
end
|
11
|
+
|
12
|
+
def call(*)
|
13
|
+
default_store, default_password = fetch_credentials
|
14
|
+
store = ask_store(default_store) || default_store
|
15
|
+
password = ask_password(default_password) || default_password
|
16
|
+
themeid = ask_theme(store: store, password: password)
|
17
|
+
env = options.flags[:env]
|
18
|
+
|
19
|
+
Themekit.generate_env(@ctx, store: store, password: password, themeid: themeid, env: env)
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.help
|
23
|
+
ShopifyCli::Context.message('theme.generate.env.help', ShopifyCli::TOOL_NAME)
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def fetch_credentials
|
29
|
+
unless File.exist?('config.yml')
|
30
|
+
return nil
|
31
|
+
end
|
32
|
+
|
33
|
+
config = YAML.load_file('config.yml')
|
34
|
+
store = config['development']['store']
|
35
|
+
password = config['development']['password']
|
36
|
+
|
37
|
+
[store, password]
|
38
|
+
end
|
39
|
+
|
40
|
+
def ask_store(default)
|
41
|
+
store = options.flags[:store] ||
|
42
|
+
if default
|
43
|
+
CLI::UI::Prompt.ask(@ctx.message('theme.generate.env.ask_store_default', default))
|
44
|
+
else
|
45
|
+
CLI::UI::Prompt.ask(@ctx.message('theme.generate.env.ask_store'), allow_empty: false)
|
46
|
+
end
|
47
|
+
return nil if store.empty?
|
48
|
+
store
|
49
|
+
end
|
50
|
+
|
51
|
+
def ask_password(default)
|
52
|
+
password = options.flags[:password] ||
|
53
|
+
if default
|
54
|
+
CLI::UI::Prompt.ask(@ctx.message('theme.generate.env.ask_password_default', default))
|
55
|
+
else
|
56
|
+
CLI::UI::Prompt.ask(@ctx.message('theme.generate.env.ask_password'), allow_empty: false)
|
57
|
+
end
|
58
|
+
return nil if password.empty?
|
59
|
+
password
|
60
|
+
end
|
61
|
+
|
62
|
+
def ask_theme(store:, password:)
|
63
|
+
theme = options.flags[:themeid]
|
64
|
+
return theme if theme
|
65
|
+
|
66
|
+
themes = Themekit.query_themes(@ctx, store: store, password: password)
|
67
|
+
|
68
|
+
@ctx.abort(@ctx.message('theme.generate.env.no_themes', ShopifyCli::TOOL_NAME)) if themes.empty?
|
69
|
+
|
70
|
+
CLI::UI::Prompt.ask(@ctx.message('theme.generate.env.ask_theme')) do |handler|
|
71
|
+
themes.each do |name, id|
|
72
|
+
handler.option(name) { id }
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module Theme
|
3
|
+
module Commands
|
4
|
+
class Push < ShopifyCli::Command
|
5
|
+
prerequisite_task :ensure_themekit_installed
|
6
|
+
|
7
|
+
options do |parser, flags|
|
8
|
+
parser.on('--remove') { flags['remove'] = true }
|
9
|
+
parser.on('--nodelete') { flags['nodelete'] = true }
|
10
|
+
parser.on('--allow-live') { flags['allow-live'] = true }
|
11
|
+
parser.on('--env=ENV') { |env| flags[:env] = env }
|
12
|
+
end
|
13
|
+
|
14
|
+
def call(args, _name)
|
15
|
+
if options.flags['remove']
|
16
|
+
remove = true
|
17
|
+
options.flags.delete('remove')
|
18
|
+
end
|
19
|
+
|
20
|
+
if options.flags[:env]
|
21
|
+
env = options.flags[:env]
|
22
|
+
options.flags.delete(:env)
|
23
|
+
end
|
24
|
+
|
25
|
+
flags = Themekit.add_flags(options.flags)
|
26
|
+
|
27
|
+
if remove
|
28
|
+
CLI::UI::Frame.open(@ctx.message('theme.push.remove')) do
|
29
|
+
unless CLI::UI::Prompt.confirm(@ctx.message('theme.push.remove_confirm'))
|
30
|
+
@ctx.abort(@ctx.message('theme.push.remove_abort'))
|
31
|
+
end
|
32
|
+
|
33
|
+
unless Themekit.push(@ctx, files: args, flags: flags, remove: remove, env: env)
|
34
|
+
@ctx.abort(@ctx.message('theme.push.error.remove_error'))
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
@ctx.done(@ctx.message('theme.push.info.remove', @ctx.root))
|
39
|
+
else
|
40
|
+
CLI::UI::Frame.open(@ctx.message('theme.push.push')) do
|
41
|
+
unless Themekit.push(@ctx, files: args, flags: flags, remove: remove, env: env)
|
42
|
+
@ctx.abort(@ctx.message('theme.push.error.push_error'))
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
@ctx.done(@ctx.message('theme.push.info.push', @ctx.root))
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def self.help
|
51
|
+
ShopifyCli::Context.message('theme.push.help', ShopifyCli::TOOL_NAME, ShopifyCli::TOOL_NAME)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module Theme
|
3
|
+
module Commands
|
4
|
+
class Serve < ShopifyCli::Command
|
5
|
+
prerequisite_task :ensure_themekit_installed
|
6
|
+
|
7
|
+
options do |parser, flags|
|
8
|
+
parser.on('--env=ENV') { |env| flags[:env] = env }
|
9
|
+
parser.on('--allow-live') { flags['allow-live'] = true }
|
10
|
+
parser.on('--notify=FILES') { |files| flags['notify'] = files }
|
11
|
+
end
|
12
|
+
|
13
|
+
def call(*)
|
14
|
+
if options.flags[:env]
|
15
|
+
env = options.flags[:env]
|
16
|
+
options.flags.delete(:env)
|
17
|
+
end
|
18
|
+
|
19
|
+
flags = Themekit.add_flags(options.flags)
|
20
|
+
|
21
|
+
CLI::UI::Frame.open(@ctx.message('theme.serve.serve')) do
|
22
|
+
Themekit.serve(@ctx, flags: flags, env: env)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.help
|
27
|
+
ShopifyCli::Context.message('theme.serve.help', ShopifyCli::TOOL_NAME)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module Theme
|
2
|
+
module Forms
|
3
|
+
class Connect < ShopifyCli::Form
|
4
|
+
attr_accessor :name
|
5
|
+
flag_arguments :themeid, :password, :store, :env
|
6
|
+
|
7
|
+
def ask
|
8
|
+
self.store ||= CLI::UI::Prompt.ask(ctx.message('theme.forms.ask_store'), allow_empty: false)
|
9
|
+
ctx.puts(ctx.message('theme.forms.connect.private_app', store))
|
10
|
+
self.password ||= CLI::UI::Prompt.ask(ctx.message('theme.forms.ask_password'), allow_empty: false)
|
11
|
+
|
12
|
+
errors = []
|
13
|
+
errors << "store" if store.strip.empty?
|
14
|
+
errors << "password" if password.strip.empty?
|
15
|
+
ctx.abort(ctx.message('theme.forms.errors', errors.join(", ").capitalize)) unless errors.empty?
|
16
|
+
|
17
|
+
self.themeid, self.name = ask_theme(store: store, password: password, themeid: themeid)
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def ask_theme(store:, password:, themeid:)
|
23
|
+
themes = Themekit.query_themes(@ctx, store: store, password: password)
|
24
|
+
|
25
|
+
themeid ||= CLI::UI::Prompt.ask("Select theme") do |handler|
|
26
|
+
themes.each do |name, id|
|
27
|
+
handler.option(name) { id }
|
28
|
+
end
|
29
|
+
end
|
30
|
+
[themeid, themes.key(themeid.to_i)]
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Theme
|
2
|
+
module Forms
|
3
|
+
class Create < ShopifyCli::Form
|
4
|
+
attr_accessor :name
|
5
|
+
flag_arguments :title, :password, :store, :env
|
6
|
+
|
7
|
+
def ask
|
8
|
+
self.store ||= CLI::UI::Prompt.ask(ctx.message('theme.forms.ask_store'), allow_empty: false)
|
9
|
+
ctx.puts(ctx.message('theme.forms.create.private_app', store))
|
10
|
+
self.password ||= CLI::UI::Prompt.ask(ctx.message('theme.forms.ask_password'), allow_empty: false)
|
11
|
+
self.title ||= CLI::UI::Prompt.ask(ctx.message('theme.forms.create.ask_title'), allow_empty: false)
|
12
|
+
self.name = self.title.downcase.split(" ").join("_")
|
13
|
+
|
14
|
+
errors = []
|
15
|
+
errors << "store" if store.strip.empty?
|
16
|
+
errors << "password" if password.strip.empty?
|
17
|
+
errors << "title" if title.strip.empty?
|
18
|
+
ctx.abort(ctx.message('theme.forms.errors', errors.join(", ").capitalize)) unless errors.empty?
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,147 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module Theme
|
3
|
+
module Messages
|
4
|
+
MESSAGES = {
|
5
|
+
theme: {
|
6
|
+
connect: {
|
7
|
+
duplicate: "Duplicate directory, theme files weren't connected",
|
8
|
+
help: <<~HELP,
|
9
|
+
{{command:%s connect theme}}: Connects an existing theme in your store to Shopify App CLI. Downloads a copy of the theme files to your local development environment.
|
10
|
+
Usage: {{command:%s connect theme}}
|
11
|
+
Options:
|
12
|
+
{{command:--store=MYSHOPIFYDOMAIN}} Store URL. Must be an existing store with private apps enabled.
|
13
|
+
{{command:--password=PASSWORD}} Private app password. App must have Read and Write Theme access.
|
14
|
+
{{command:--themeid=THEMEID}} Theme ID. Must be an existing theme on your store.
|
15
|
+
HELP
|
16
|
+
inside_project: "You are inside an existing theme, theme files weren't connected",
|
17
|
+
connect: "Downloading theme files...",
|
18
|
+
failed: "Couldn't download theme files from store",
|
19
|
+
connected: "{{green:%s}} files were downloaded from {{underline:%s}} to {{green:%s}}",
|
20
|
+
},
|
21
|
+
create: {
|
22
|
+
creating_theme: "Creating theme %s",
|
23
|
+
duplicate_theme: "Duplicate theme",
|
24
|
+
failed: "Couldn't create the theme",
|
25
|
+
help: <<~HELP,
|
26
|
+
{{command:%s create theme}}: Creates a theme.
|
27
|
+
Usage: {{command:%s create theme}}
|
28
|
+
Options:
|
29
|
+
{{command:--store=MYSHOPIFYDOMAIN}} Store URL. Must be an existing store with private apps enabled.
|
30
|
+
{{command:--password=PASSWORD}} Private app password. App must have Read and Write Theme access.
|
31
|
+
{{command:--name=NAME}} Theme name. Any string.
|
32
|
+
HELP
|
33
|
+
info: {
|
34
|
+
created: "{{green:%s}} was created for {{underline:%s}} in {{green:%s}}",
|
35
|
+
},
|
36
|
+
},
|
37
|
+
deploy: {
|
38
|
+
abort: "Theme wasn't deployed",
|
39
|
+
confirmation: "This will change your live theme. Do you wish to proceed?",
|
40
|
+
deploying: "Deploying theme",
|
41
|
+
error: "Theme couldn't be deployed",
|
42
|
+
help: <<~HELP,
|
43
|
+
{{command:%s deploy}}: Uploads your local theme files to Shopify, then sets your theme as the live theme.
|
44
|
+
Usage: {{command:%s deploy}}
|
45
|
+
HELP
|
46
|
+
info: {
|
47
|
+
deployed: "Theme was updated and set as the live theme",
|
48
|
+
pushed: "All theme files were updated",
|
49
|
+
},
|
50
|
+
push_fail: "Theme files couldn't be updated",
|
51
|
+
},
|
52
|
+
forms: {
|
53
|
+
ask_password: "Password:",
|
54
|
+
ask_store: "Store domain:",
|
55
|
+
create: {
|
56
|
+
ask_title: "Title:",
|
57
|
+
private_app: <<~APP,
|
58
|
+
To create a new theme, Shopify App CLI needs to connect with a private app installed on your store. Visit {{underline:%s/admin/apps/private}} to create a new API key and password, or retrieve an existing password.
|
59
|
+
If you create a new private app, ensure that it has Read and Write Theme access.
|
60
|
+
APP
|
61
|
+
},
|
62
|
+
connect: {
|
63
|
+
private_app: <<~APP,
|
64
|
+
To fetch your existing themes, Shopify App CLI needs to connect with your store. Visit {{underline:%s/admin/apps/private}} to create a new API key and password, or retrieve an existing password.
|
65
|
+
If you create a new private app, ensure that it has Read and Write Theme access.
|
66
|
+
APP
|
67
|
+
},
|
68
|
+
errors: "%s can't be blank",
|
69
|
+
},
|
70
|
+
generate: {
|
71
|
+
env: {
|
72
|
+
ask_password: "Password",
|
73
|
+
ask_password_default: "Password (defaults to {{green:%s}})",
|
74
|
+
ask_store: "Store",
|
75
|
+
ask_store_default: "Store (defaults to {{green:%s}})",
|
76
|
+
ask_theme: "Select theme",
|
77
|
+
help: <<~HELP,
|
78
|
+
Create or update configuration file in the current directory.
|
79
|
+
Usage: {{command:%s generate env}}
|
80
|
+
Options:
|
81
|
+
{{command:--store=MYSHOPIFYDOMAIN}} Store URL. Must be an existing store with private apps enabled.
|
82
|
+
{{command:--password=PASSWORD}} Private app password. App must have Read and Write Theme access.
|
83
|
+
{{command:--themeid=THEMEID}} Theme ID. Must be an existing theme on your store.
|
84
|
+
HELP
|
85
|
+
no_themes: "Please create a new theme using %s create theme",
|
86
|
+
},
|
87
|
+
help: <<~HELP,
|
88
|
+
Generate code in your Theme. Currently supports generating new envs.
|
89
|
+
Usage: {{command:%s generate [ env ]}}
|
90
|
+
HELP
|
91
|
+
},
|
92
|
+
push: {
|
93
|
+
remove_abort: "Theme files weren't deleted",
|
94
|
+
remove_confirm: "This will delete the local and remote copies of the theme files. Do you wish to proceed?",
|
95
|
+
error: {
|
96
|
+
push_error: "Theme files couldn't be pushed to Shopify",
|
97
|
+
remove_error: "Theme files couldn't be removed from Shopify",
|
98
|
+
},
|
99
|
+
help: <<~HELP,
|
100
|
+
{{command:%s push}}: Uploads your local theme files to Shopify, overwriting the remote versions. If you specify filenames, separated by a space, only those files will be replaced. Otherwise, the whole theme will be replaced.
|
101
|
+
Usage: {{command:%s push}}
|
102
|
+
Options:
|
103
|
+
{{command:--remove}} Deletes both the local and the remote copies of the specified files. At least one filename must be specified.
|
104
|
+
{{command:--allow-live}} Allows Shopify App CLI to replace files on the store's live production theme.
|
105
|
+
{{command:--nodelete}} Runs the push command without deleting remote files from Shopify.
|
106
|
+
HELP
|
107
|
+
info: {
|
108
|
+
push: "Theme files were pushed from {{green:%s}} to Shopify",
|
109
|
+
remove: "Theme files were deleted from {{green:%s}} and Shopify",
|
110
|
+
},
|
111
|
+
push: "Pushing theme files to Shopify",
|
112
|
+
remove: "Deleting theme files",
|
113
|
+
},
|
114
|
+
serve: {
|
115
|
+
help: <<~HELP,
|
116
|
+
Sync your current changes, then view the active store in your default browser. Any theme edits will continue to update in real time. Also prints the active store's URL in your terminal.
|
117
|
+
Usage: {{command:%s serve}}
|
118
|
+
HELP
|
119
|
+
serve: "Viewing theme...",
|
120
|
+
open_fail: "Couldn't open the theme",
|
121
|
+
},
|
122
|
+
tasks: {
|
123
|
+
ensure_themekit_installed: {
|
124
|
+
auto_update: "Would you like to enable auto-updating?",
|
125
|
+
downloading: "Downloading Theme Kit %s",
|
126
|
+
errors: {
|
127
|
+
digest_fail: "Unable to verify download",
|
128
|
+
releases_fail: "Unable to fetch Theme Kit's list of releases",
|
129
|
+
update_fail: "Unable to update Theme Kit",
|
130
|
+
write_fail: "Unable to download Theme Kit",
|
131
|
+
},
|
132
|
+
installing_themekit: "Installing Theme Kit",
|
133
|
+
successful: "Theme Kit installed successfully",
|
134
|
+
updating_themekit: "Updating Theme Kit",
|
135
|
+
verifying: "Verifying download...",
|
136
|
+
},
|
137
|
+
},
|
138
|
+
themekit: {
|
139
|
+
query_themes: {
|
140
|
+
bad_password: "Bad password",
|
141
|
+
not_connect: "Couldn't connect to given shop",
|
142
|
+
},
|
143
|
+
},
|
144
|
+
},
|
145
|
+
}.freeze
|
146
|
+
end
|
147
|
+
end
|