shopify-cli 0.9.0
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.
- checksums.yaml +7 -0
- data/.github/CODEOWNERS +1 -0
- data/.github/CODE_OF_CONDUCT.md +73 -0
- data/.github/CONTRIBUTING.md +51 -0
- data/.github/DESIGN.md +153 -0
- data/.github/ISSUE_TEMPLATE.md +38 -0
- data/.github/PULL_REQUEST_TEMPLATE.md +22 -0
- data/.github/probots.yml +3 -0
- data/.gitignore +19 -0
- data/.rubocop.yml +47 -0
- data/.ruby-version +1 -0
- data/.travis.yml +12 -0
- data/Gemfile +22 -0
- data/Gemfile.lock +77 -0
- data/LICENSE.md +7 -0
- data/README.md +13 -0
- data/Rakefile +101 -0
- data/SECURITY.md +59 -0
- data/Vagrantfile +17 -0
- data/bin/load_shopify.rb +20 -0
- data/bin/shopify +32 -0
- data/dev.yml +17 -0
- data/docs/Gemfile +5 -0
- data/docs/Gemfile.lock +248 -0
- data/docs/_config.yml +16 -0
- data/docs/_data/nav.yml +26 -0
- data/docs/_includes/footer.html +15 -0
- data/docs/_includes/head.html +19 -0
- data/docs/_includes/sidebar_nav.html +22 -0
- data/docs/_includes/toc.html +112 -0
- data/docs/_layouts/default.html +79 -0
- data/docs/app/node/commands/index.md +82 -0
- data/docs/app/node/index.md +35 -0
- data/docs/app/rails/commands/index.md +80 -0
- data/docs/app/rails/index.md +36 -0
- data/docs/core/index.md +70 -0
- data/docs/css/docs.css +157 -0
- data/docs/getting-started/index.md +61 -0
- data/docs/help/start-app/index.md +6 -0
- data/docs/images/header.png +0 -0
- data/docs/index.md +27 -0
- data/docs/installing-ruby.md +28 -0
- data/ext/shopify-cli/extconf.rb +27 -0
- data/install.sh +7 -0
- data/lib/docgen/class_template.md.erb +81 -0
- data/lib/docgen/index_template.md.erb +5 -0
- data/lib/docgen/markdown.rb +101 -0
- data/lib/graphql/admin_introspection.graphql +87 -0
- data/lib/graphql/all_organizations.graphql +19 -0
- data/lib/graphql/all_orgs_with_apps.graphql +30 -0
- data/lib/graphql/api_versions.graphql +6 -0
- data/lib/graphql/convert_dev_to_test_store.graphql +10 -0
- data/lib/graphql/create_app.graphql +20 -0
- data/lib/graphql/create_customer.graphql +9 -0
- data/lib/graphql/create_draft_order.graphql +8 -0
- data/lib/graphql/create_product.graphql +9 -0
- data/lib/graphql/extension_create.graphql +21 -0
- data/lib/graphql/extension_update_draft.graphql +18 -0
- data/lib/graphql/find_organization.graphql +17 -0
- data/lib/graphql/get_app_urls.graphql +6 -0
- data/lib/graphql/update_dashboard_urls.graphql +8 -0
- data/lib/project_types/extension/cli.rb +71 -0
- data/lib/project_types/extension/commands/build.rb +29 -0
- data/lib/project_types/extension/commands/create.rb +49 -0
- data/lib/project_types/extension/commands/extension_command.rb +22 -0
- data/lib/project_types/extension/commands/push.rb +69 -0
- data/lib/project_types/extension/commands/register.rb +78 -0
- data/lib/project_types/extension/commands/serve.rb +24 -0
- data/lib/project_types/extension/commands/tunnel.rb +69 -0
- data/lib/project_types/extension/extension_project.rb +85 -0
- data/lib/project_types/extension/extension_project_keys.rb +10 -0
- data/lib/project_types/extension/features/argo.rb +48 -0
- data/lib/project_types/extension/features/argo_dependencies.rb +28 -0
- data/lib/project_types/extension/features/argo_setup.rb +54 -0
- data/lib/project_types/extension/features/argo_setup_step.rb +31 -0
- data/lib/project_types/extension/features/argo_setup_steps.rb +53 -0
- data/lib/project_types/extension/features/tunnel_url.rb +20 -0
- data/lib/project_types/extension/forms/create.rb +52 -0
- data/lib/project_types/extension/forms/register.rb +48 -0
- data/lib/project_types/extension/messages/message_loading.rb +37 -0
- data/lib/project_types/extension/messages/messages.rb +126 -0
- data/lib/project_types/extension/models/app.rb +14 -0
- data/lib/project_types/extension/models/registration.rb +19 -0
- data/lib/project_types/extension/models/type.rb +76 -0
- data/lib/project_types/extension/models/types/checkout_post_purchase.rb +20 -0
- data/lib/project_types/extension/models/types/subscription_management.rb +20 -0
- data/lib/project_types/extension/models/validation_error.rb +17 -0
- data/lib/project_types/extension/models/version.rb +15 -0
- data/lib/project_types/extension/tasks/converters/registration_converter.rb +26 -0
- data/lib/project_types/extension/tasks/converters/validation_error_converter.rb +25 -0
- data/lib/project_types/extension/tasks/converters/version_converter.rb +28 -0
- data/lib/project_types/extension/tasks/create_extension.rb +31 -0
- data/lib/project_types/extension/tasks/get_apps.rb +34 -0
- data/lib/project_types/extension/tasks/update_draft.rb +29 -0
- data/lib/project_types/extension/tasks/user_errors.rb +45 -0
- data/lib/project_types/node/cli.rb +37 -0
- data/lib/project_types/node/commands/create.rb +117 -0
- data/lib/project_types/node/commands/deploy.rb +22 -0
- data/lib/project_types/node/commands/deploy/heroku.rb +91 -0
- data/lib/project_types/node/commands/generate.rb +51 -0
- data/lib/project_types/node/commands/generate/billing.rb +37 -0
- data/lib/project_types/node/commands/generate/page.rb +55 -0
- data/lib/project_types/node/commands/generate/webhook.rb +33 -0
- data/lib/project_types/node/commands/open.rb +16 -0
- data/lib/project_types/node/commands/populate.rb +23 -0
- data/lib/project_types/node/commands/populate/customer.rb +31 -0
- data/lib/project_types/node/commands/populate/draft_order.rb +28 -0
- data/lib/project_types/node/commands/populate/product.rb +30 -0
- data/lib/project_types/node/commands/serve.rb +45 -0
- data/lib/project_types/node/commands/tunnel.rb +39 -0
- data/lib/project_types/node/forms/create.rb +87 -0
- data/lib/project_types/node/messages/messages.rb +260 -0
- data/lib/project_types/rails/cli.rb +41 -0
- data/lib/project_types/rails/commands/create.rb +126 -0
- data/lib/project_types/rails/commands/deploy.rb +22 -0
- data/lib/project_types/rails/commands/deploy/heroku.rb +113 -0
- data/lib/project_types/rails/commands/generate.rb +49 -0
- data/lib/project_types/rails/commands/generate/webhook.rb +39 -0
- data/lib/project_types/rails/commands/open.rb +16 -0
- data/lib/project_types/rails/commands/populate.rb +23 -0
- data/lib/project_types/rails/commands/populate/customer.rb +31 -0
- data/lib/project_types/rails/commands/populate/draft_order.rb +28 -0
- data/lib/project_types/rails/commands/populate/product.rb +30 -0
- data/lib/project_types/rails/commands/serve.rb +47 -0
- data/lib/project_types/rails/commands/tunnel.rb +39 -0
- data/lib/project_types/rails/forms/create.rb +116 -0
- data/lib/project_types/rails/gem.rb +56 -0
- data/lib/project_types/rails/messages/messages.rb +283 -0
- data/lib/project_types/rails/ruby.rb +17 -0
- data/lib/project_types/script/cli.rb +76 -0
- data/lib/project_types/script/commands/create.rb +45 -0
- data/lib/project_types/script/commands/disable.rb +36 -0
- data/lib/project_types/script/commands/enable.rb +46 -0
- data/lib/project_types/script/commands/push.rb +39 -0
- data/lib/project_types/script/config/extension_points.yml +18 -0
- data/lib/project_types/script/errors.rb +16 -0
- data/lib/project_types/script/forms/create.rb +29 -0
- data/lib/project_types/script/forms/enable.rb +24 -0
- data/lib/project_types/script/forms/push.rb +19 -0
- data/lib/project_types/script/forms/script_form.rb +66 -0
- data/lib/project_types/script/graphql/app_script_update_or_create.graphql +27 -0
- data/lib/project_types/script/graphql/script_service_proxy.graphql +8 -0
- data/lib/project_types/script/graphql/shop_script_delete.graphql +14 -0
- data/lib/project_types/script/graphql/shop_script_update_or_create.graphql +28 -0
- data/lib/project_types/script/layers/application/build_script.rb +43 -0
- data/lib/project_types/script/layers/application/create_script.rb +47 -0
- data/lib/project_types/script/layers/application/disable_script.rb +19 -0
- data/lib/project_types/script/layers/application/enable_script.rb +21 -0
- data/lib/project_types/script/layers/application/extension_points.rb +17 -0
- data/lib/project_types/script/layers/application/project_dependencies.rb +34 -0
- data/lib/project_types/script/layers/application/push_script.rb +30 -0
- data/lib/project_types/script/layers/domain/errors.rb +25 -0
- data/lib/project_types/script/layers/domain/extension_point.rb +29 -0
- data/lib/project_types/script/layers/domain/push_package.rb +29 -0
- data/lib/project_types/script/layers/domain/script.rb +18 -0
- data/lib/project_types/script/layers/infrastructure/assemblyscript_dependency_manager.rb +73 -0
- data/lib/project_types/script/layers/infrastructure/assemblyscript_tsconfig.rb +38 -0
- data/lib/project_types/script/layers/infrastructure/assemblyscript_wasm_builder.rb +39 -0
- data/lib/project_types/script/layers/infrastructure/dependency_manager.rb +36 -0
- data/lib/project_types/script/layers/infrastructure/errors.rb +38 -0
- data/lib/project_types/script/layers/infrastructure/extension_point_repository.rb +31 -0
- data/lib/project_types/script/layers/infrastructure/push_package_repository.rb +47 -0
- data/lib/project_types/script/layers/infrastructure/script_builder.rb +34 -0
- data/lib/project_types/script/layers/infrastructure/script_repository.rb +89 -0
- data/lib/project_types/script/layers/infrastructure/script_service.rb +165 -0
- data/lib/project_types/script/layers/infrastructure/test_suite_repository.rb +59 -0
- data/lib/project_types/script/messages/messages.rb +204 -0
- data/lib/project_types/script/script_project.rb +37 -0
- data/lib/project_types/script/templates/ts/as-pect.config.js +21 -0
- data/lib/project_types/script/ui/error_handler.rb +136 -0
- data/lib/project_types/script/ui/strict_spinner.rb +22 -0
- data/lib/rubygems_plugin.rb +18 -0
- data/lib/shopify-cli/admin_api.rb +99 -0
- data/lib/shopify-cli/admin_api/populate_resource_command.rb +165 -0
- data/lib/shopify-cli/admin_api/schema.rb +32 -0
- data/lib/shopify-cli/api.rb +104 -0
- data/lib/shopify-cli/command.rb +67 -0
- data/lib/shopify-cli/commands.rb +28 -0
- data/lib/shopify-cli/commands/connect.rb +108 -0
- data/lib/shopify-cli/commands/create.rb +50 -0
- data/lib/shopify-cli/commands/help.rb +79 -0
- data/lib/shopify-cli/commands/logout.rb +23 -0
- data/lib/shopify-cli/commands/system.rb +135 -0
- data/lib/shopify-cli/commands/version.rb +15 -0
- data/lib/shopify-cli/context.rb +372 -0
- data/lib/shopify-cli/core.rb +9 -0
- data/lib/shopify-cli/core/entry_point.rb +40 -0
- data/lib/shopify-cli/core/executor.rb +21 -0
- data/lib/shopify-cli/core/help_resolver.rb +20 -0
- data/lib/shopify-cli/core/monorail.rb +118 -0
- data/lib/shopify-cli/db.rb +114 -0
- data/lib/shopify-cli/form.rb +40 -0
- data/lib/shopify-cli/git.rb +141 -0
- data/lib/shopify-cli/helpers.rb +5 -0
- data/lib/shopify-cli/helpers/haikunator.rb +92 -0
- data/lib/shopify-cli/heroku.rb +97 -0
- data/lib/shopify-cli/js_deps.rb +110 -0
- data/lib/shopify-cli/js_system.rb +98 -0
- data/lib/shopify-cli/messages/messages.rb +287 -0
- data/lib/shopify-cli/oauth.rb +192 -0
- data/lib/shopify-cli/oauth/servlet.rb +61 -0
- data/lib/shopify-cli/options.rb +40 -0
- data/lib/shopify-cli/packager.rb +116 -0
- data/lib/shopify-cli/partners_api.rb +114 -0
- data/lib/shopify-cli/partners_api/organizations.rb +32 -0
- data/lib/shopify-cli/process_supervision.rb +187 -0
- data/lib/shopify-cli/project.rb +191 -0
- data/lib/shopify-cli/project_type.rb +83 -0
- data/lib/shopify-cli/resources.rb +5 -0
- data/lib/shopify-cli/resources/env_file.rb +96 -0
- data/lib/shopify-cli/sub_command.rb +15 -0
- data/lib/shopify-cli/task.rb +10 -0
- data/lib/shopify-cli/tasks.rb +32 -0
- data/lib/shopify-cli/tasks/create_api_client.rb +29 -0
- data/lib/shopify-cli/tasks/ensure_dev_store.rb +41 -0
- data/lib/shopify-cli/tasks/ensure_env.rb +31 -0
- data/lib/shopify-cli/tasks/ensure_loopback_url.rb +20 -0
- data/lib/shopify-cli/tasks/update_dashboard_urls.rb +44 -0
- data/lib/shopify-cli/tunnel.rb +154 -0
- data/lib/shopify-cli/version.rb +3 -0
- data/lib/shopify_cli.rb +132 -0
- data/shopify-cli.gemspec +40 -0
- data/shopify.fish +12 -0
- data/shopify.sh +11 -0
- data/vendor/deps/cli-kit/REVISION +1 -0
- data/vendor/deps/cli-kit/lib/cli/kit.rb +60 -0
- data/vendor/deps/cli-kit/lib/cli/kit/autocall.rb +21 -0
- data/vendor/deps/cli-kit/lib/cli/kit/base_command.rb +49 -0
- data/vendor/deps/cli-kit/lib/cli/kit/command_registry.rb +94 -0
- data/vendor/deps/cli-kit/lib/cli/kit/config.rb +133 -0
- data/vendor/deps/cli-kit/lib/cli/kit/error_handler.rb +115 -0
- data/vendor/deps/cli-kit/lib/cli/kit/executor.rb +81 -0
- data/vendor/deps/cli-kit/lib/cli/kit/ini.rb +102 -0
- data/vendor/deps/cli-kit/lib/cli/kit/levenshtein.rb +82 -0
- data/vendor/deps/cli-kit/lib/cli/kit/logger.rb +76 -0
- data/vendor/deps/cli-kit/lib/cli/kit/resolver.rb +60 -0
- data/vendor/deps/cli-kit/lib/cli/kit/ruby_backports/enumerable.rb +6 -0
- data/vendor/deps/cli-kit/lib/cli/kit/support.rb +9 -0
- data/vendor/deps/cli-kit/lib/cli/kit/support/test_helper.rb +244 -0
- data/vendor/deps/cli-kit/lib/cli/kit/system.rb +207 -0
- data/vendor/deps/cli-kit/lib/cli/kit/util.rb +189 -0
- data/vendor/deps/cli-kit/lib/cli/kit/version.rb +5 -0
- data/vendor/deps/cli-ui/REVISION +1 -0
- data/vendor/deps/cli-ui/lib/cli/ui.rb +187 -0
- data/vendor/deps/cli-ui/lib/cli/ui/ansi.rb +153 -0
- data/vendor/deps/cli-ui/lib/cli/ui/box.rb +15 -0
- data/vendor/deps/cli-ui/lib/cli/ui/color.rb +79 -0
- data/vendor/deps/cli-ui/lib/cli/ui/formatter.rb +179 -0
- data/vendor/deps/cli-ui/lib/cli/ui/frame.rb +310 -0
- data/vendor/deps/cli-ui/lib/cli/ui/glyph.rb +78 -0
- data/vendor/deps/cli-ui/lib/cli/ui/progress.rb +88 -0
- data/vendor/deps/cli-ui/lib/cli/ui/prompt.rb +248 -0
- data/vendor/deps/cli-ui/lib/cli/ui/prompt/interactive_options.rb +472 -0
- data/vendor/deps/cli-ui/lib/cli/ui/prompt/options_handler.rb +24 -0
- data/vendor/deps/cli-ui/lib/cli/ui/spinner.rb +48 -0
- data/vendor/deps/cli-ui/lib/cli/ui/spinner/async.rb +40 -0
- data/vendor/deps/cli-ui/lib/cli/ui/spinner/spin_group.rb +241 -0
- data/vendor/deps/cli-ui/lib/cli/ui/stdout_router.rb +227 -0
- data/vendor/deps/cli-ui/lib/cli/ui/terminal.rb +36 -0
- data/vendor/deps/cli-ui/lib/cli/ui/truncater.rb +102 -0
- data/vendor/deps/cli-ui/lib/cli/ui/version.rb +5 -0
- data/vendor/deps/smart_properties/REVISION +1 -0
- data/vendor/deps/smart_properties/lib/smart_properties.rb +174 -0
- data/vendor/deps/smart_properties/lib/smart_properties/errors.rb +114 -0
- data/vendor/deps/smart_properties/lib/smart_properties/property.rb +162 -0
- data/vendor/deps/smart_properties/lib/smart_properties/property_collection.rb +83 -0
- data/vendor/deps/smart_properties/lib/smart_properties/validations.rb +8 -0
- data/vendor/deps/smart_properties/lib/smart_properties/validations/ancestor.rb +27 -0
- data/vendor/deps/smart_properties/lib/smart_properties/version.rb +3 -0
- data/vendor/lib/semantic/LICENSE +20 -0
- data/vendor/lib/semantic/semantic.rb +4 -0
- data/vendor/lib/semantic/version.rb +180 -0
- metadata +374 -0
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
module ShopifyCli
|
|
2
|
+
module Core
|
|
3
|
+
autoload :EntryPoint, 'shopify-cli/core/entry_point'
|
|
4
|
+
autoload :Executor, 'shopify-cli/core/executor'
|
|
5
|
+
autoload :HelpResolver, 'shopify-cli/core/help_resolver'
|
|
6
|
+
autoload :Monorail, 'shopify-cli/core/monorail'
|
|
7
|
+
autoload :Update, 'shopify-cli/core/update'
|
|
8
|
+
end
|
|
9
|
+
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
require 'shopify_cli'
|
|
2
|
+
|
|
3
|
+
module ShopifyCli
|
|
4
|
+
module Core
|
|
5
|
+
module EntryPoint
|
|
6
|
+
class << self
|
|
7
|
+
def call(args, ctx = Context.new)
|
|
8
|
+
# Check if the shim is set up by checking whether the old Finalizer FD exists
|
|
9
|
+
begin
|
|
10
|
+
is_shell_shim = false
|
|
11
|
+
IO.open(9) { is_shell_shim = true }
|
|
12
|
+
rescue Errno::EBADF
|
|
13
|
+
# This is expected if the descriptor doesn't exist
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
if !ctx.testing? && is_shell_shim
|
|
17
|
+
ctx.puts(ctx.message('core.warning.shell_shim'))
|
|
18
|
+
return
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
if ctx.development?
|
|
22
|
+
ctx.puts(
|
|
23
|
+
ctx.message('core.warning.development_version', File.join(ShopifyCli::ROOT, 'bin', ShopifyCli::TOOL_NAME))
|
|
24
|
+
)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
ProjectType.load_type(Project.current_project_type)
|
|
28
|
+
|
|
29
|
+
task_registry = ShopifyCli::Tasks::Registry
|
|
30
|
+
|
|
31
|
+
command, command_name, args = ShopifyCli::Resolver.call(args)
|
|
32
|
+
executor = ShopifyCli::Core::Executor.new(ctx, task_registry, log_file: ShopifyCli::LOG_FILE)
|
|
33
|
+
ShopifyCli::Core::Monorail.log(command_name, args) do
|
|
34
|
+
executor.call(command, command_name, args)
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
require 'shopify_cli'
|
|
2
|
+
|
|
3
|
+
module ShopifyCli
|
|
4
|
+
module Core
|
|
5
|
+
class Executor < CLI::Kit::Executor
|
|
6
|
+
def initialize(ctx, task_registry, *args)
|
|
7
|
+
@ctx = ctx || ShopifyCli::Context.new
|
|
8
|
+
@task_registry = task_registry || ShopifyCli::Tasks::TaskRegistry.new
|
|
9
|
+
super(*args)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def call(command, command_name, args)
|
|
13
|
+
command.prerequisite_tasks.each do |task, _|
|
|
14
|
+
@task_registry[task]&.call(@ctx)
|
|
15
|
+
end
|
|
16
|
+
command.ctx = @ctx
|
|
17
|
+
super
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
require 'cli/kit'
|
|
2
|
+
|
|
3
|
+
module ShopifyCli
|
|
4
|
+
module Core
|
|
5
|
+
class HelpResolver < CLI::Kit::Resolver
|
|
6
|
+
def call(args)
|
|
7
|
+
args = args.dup
|
|
8
|
+
return super(args) unless args.first
|
|
9
|
+
if args.first.include?('-h') || args.first.include?('--help')
|
|
10
|
+
help = Commands::Help
|
|
11
|
+
help.ctx = Context.new
|
|
12
|
+
help.call([], nil)
|
|
13
|
+
raise ShopifyCli::AbortSilent
|
|
14
|
+
else
|
|
15
|
+
super(args)
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
require 'json'
|
|
2
|
+
require 'net/http'
|
|
3
|
+
require 'time'
|
|
4
|
+
require 'rbconfig'
|
|
5
|
+
|
|
6
|
+
module ShopifyCli
|
|
7
|
+
module Core
|
|
8
|
+
module Monorail
|
|
9
|
+
ENDPOINT_URI = URI.parse('https://monorail-edge.shopifycloud.com/v1/produce')
|
|
10
|
+
INVOCATIONS_SCHEMA = 'app_cli_command/4.0'
|
|
11
|
+
|
|
12
|
+
# Extra hash of data that will be sent in the payload
|
|
13
|
+
@metadata = {}
|
|
14
|
+
|
|
15
|
+
class << self
|
|
16
|
+
attr_accessor :metadata
|
|
17
|
+
|
|
18
|
+
def log(name, args, &block) # rubocop:disable Lint/UnusedMethodArgument
|
|
19
|
+
prompt_for_consent
|
|
20
|
+
return yield unless enabled? && consented?
|
|
21
|
+
|
|
22
|
+
command, command_name = Commands::Registry.lookup_command(name)
|
|
23
|
+
final_command = [command_name]
|
|
24
|
+
if command
|
|
25
|
+
subcommand, subcommand_name = command.subcommand_registry.lookup_command(args.first)
|
|
26
|
+
final_command << subcommand_name if subcommand
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
start_time = now_in_milliseconds
|
|
30
|
+
err = nil
|
|
31
|
+
begin
|
|
32
|
+
yield
|
|
33
|
+
rescue Exception => e # rubocop:disable Lint/RescueException
|
|
34
|
+
err = e
|
|
35
|
+
raise
|
|
36
|
+
ensure
|
|
37
|
+
send_event(start_time, final_command, args - final_command, err&.message)
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
private
|
|
42
|
+
|
|
43
|
+
def now_in_milliseconds
|
|
44
|
+
(Time.now.utc.to_f * 1000).to_i
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# we only want to send Monorail events in production or when explicitly developing
|
|
48
|
+
def enabled?
|
|
49
|
+
Context.new.system? || ENV['MONORAIL_REAL_EVENTS'] == '1'
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def consented?
|
|
53
|
+
ShopifyCli::Config.get_bool('analytics', 'enabled')
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def prompt_for_consent
|
|
57
|
+
return unless enabled?
|
|
58
|
+
return if ShopifyCli::Config.get_section('analytics').key?('enabled')
|
|
59
|
+
msg = Context.message('core.monorail.consent_prompt')
|
|
60
|
+
opt = CLI::UI::Prompt.confirm(msg)
|
|
61
|
+
ShopifyCli::Config.set('analytics', 'enabled', opt)
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def send_event(start_time, commands, args, err = nil)
|
|
65
|
+
end_time = now_in_milliseconds
|
|
66
|
+
headers = {
|
|
67
|
+
'Content-Type': 'application/json; charset=utf-8',
|
|
68
|
+
'X-Monorail-Edge-Event-Created-At-Ms': start_time.to_s,
|
|
69
|
+
'X-Monorail-Edge-Event-Sent-At-Ms': end_time.to_s,
|
|
70
|
+
}
|
|
71
|
+
begin
|
|
72
|
+
Net::HTTP.start(
|
|
73
|
+
ENDPOINT_URI.host,
|
|
74
|
+
ENDPOINT_URI.port,
|
|
75
|
+
# timeouts for opening a connection, reading, writing (in seconds)
|
|
76
|
+
open_timeout: 0.2, read_timeout: 0.2, write_timeout: 0.2,
|
|
77
|
+
use_ssl: ENDPOINT_URI.scheme == 'https'
|
|
78
|
+
) do |http|
|
|
79
|
+
payload = build_payload(start_time, end_time, commands, args, err)
|
|
80
|
+
post = Net::HTTP::Post.new(ENDPOINT_URI.request_uri, headers)
|
|
81
|
+
post.body = JSON.dump(payload)
|
|
82
|
+
http.request(post)
|
|
83
|
+
end
|
|
84
|
+
rescue
|
|
85
|
+
# silently fail on errors, fire-and-forget approach
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def build_payload(start_time, end_time, commands, args, err = nil)
|
|
90
|
+
{
|
|
91
|
+
schema_id: INVOCATIONS_SCHEMA,
|
|
92
|
+
payload: {
|
|
93
|
+
project_type: Project.current_project_type.to_s,
|
|
94
|
+
command: commands.join(' '),
|
|
95
|
+
args: args.join(' '),
|
|
96
|
+
time_start: start_time,
|
|
97
|
+
time_end: end_time,
|
|
98
|
+
total_time: end_time - start_time,
|
|
99
|
+
success: err.nil?,
|
|
100
|
+
error_message: err,
|
|
101
|
+
uname: RbConfig::CONFIG["host"],
|
|
102
|
+
cli_version: ShopifyCli::Git.sha(dir: ShopifyCli::ROOT),
|
|
103
|
+
ruby_version: RUBY_VERSION,
|
|
104
|
+
}.tap do |payload|
|
|
105
|
+
payload[:metadata] = JSON.dump(metadata) unless metadata.empty?
|
|
106
|
+
|
|
107
|
+
if Project.has_current?
|
|
108
|
+
project = Project.current
|
|
109
|
+
payload[:api_key] = project.env&.api_key
|
|
110
|
+
payload[:partner_id] = project.config['organization_id']
|
|
111
|
+
end
|
|
112
|
+
end,
|
|
113
|
+
}
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
end
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
require 'pstore'
|
|
2
|
+
require 'forwardable'
|
|
3
|
+
|
|
4
|
+
module ShopifyCli
|
|
5
|
+
# Persists transient data like access tokens that may be cleared
|
|
6
|
+
# when user clears their session
|
|
7
|
+
#
|
|
8
|
+
# All of the instance methods documented here can be used as class methods. All class
|
|
9
|
+
# methods are forwarded to a new instance of the database, pointing at the default
|
|
10
|
+
# path.
|
|
11
|
+
class DB
|
|
12
|
+
extend SingleForwardable
|
|
13
|
+
def_delegators :new, :keys, :exists?, :set, :get, :del, :clear
|
|
14
|
+
|
|
15
|
+
attr_reader :db # :nodoc:
|
|
16
|
+
|
|
17
|
+
def initialize(path: File.join(ShopifyCli::CACHE_DIR, ".db.pstore")) # :nodoc:
|
|
18
|
+
@db = PStore.new(path)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# Get all keys that exist in the database.
|
|
22
|
+
#
|
|
23
|
+
# #### Returns
|
|
24
|
+
# - `keys`: an array of string or symbol keys that exist in the database
|
|
25
|
+
#
|
|
26
|
+
# #### Usage
|
|
27
|
+
#
|
|
28
|
+
# ShopifyCli::DB.keys
|
|
29
|
+
#
|
|
30
|
+
def keys
|
|
31
|
+
db.transaction(true) { db.roots }
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Check to see if a key exists in the database, the key will only exist if it
|
|
35
|
+
# has a value so if the key exists then there is also a value.
|
|
36
|
+
#
|
|
37
|
+
# #### Parameters
|
|
38
|
+
# - `key`: a string or a symbol representation of a key that is stored in the DB
|
|
39
|
+
#
|
|
40
|
+
# #### Returns
|
|
41
|
+
# - `exists`: a boolean value if the key exists in the database
|
|
42
|
+
#
|
|
43
|
+
# #### Usage
|
|
44
|
+
#
|
|
45
|
+
# exists = ShopifyCli::DB.exists?('admin_access_token')
|
|
46
|
+
#
|
|
47
|
+
def exists?(key)
|
|
48
|
+
db.transaction(true) { db.root?(key) }
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# Persist a value by key in the local storage
|
|
52
|
+
#
|
|
53
|
+
# #### Parameters
|
|
54
|
+
# - `**args`: a hash of keys and values to persist in the database
|
|
55
|
+
#
|
|
56
|
+
# #### Usage
|
|
57
|
+
#
|
|
58
|
+
# ShopifyCli::DB.set(admin_access_token: 'token', metric_consent: true)
|
|
59
|
+
#
|
|
60
|
+
def set(**args)
|
|
61
|
+
db.transaction do
|
|
62
|
+
args.each do |key, val|
|
|
63
|
+
if val.nil?
|
|
64
|
+
db.delete(key)
|
|
65
|
+
else
|
|
66
|
+
db[key] = val
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# Gets a value from the DB that is associated with the supplied key
|
|
73
|
+
#
|
|
74
|
+
# #### Parameters
|
|
75
|
+
# - `key`: a string or a symbol representation of a key that is stored in the DB
|
|
76
|
+
#
|
|
77
|
+
# #### Returns
|
|
78
|
+
# - `value`: will be the previously saved value or nil if the key does not exist
|
|
79
|
+
# in the database.
|
|
80
|
+
#
|
|
81
|
+
# #### Usage
|
|
82
|
+
#
|
|
83
|
+
# ShopifyCli::DB.get(:admin_access_token)
|
|
84
|
+
#
|
|
85
|
+
def get(key)
|
|
86
|
+
val = db.transaction(true) { db[key] }
|
|
87
|
+
val = yield if val.nil? && block_given?
|
|
88
|
+
val
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
# Deletes a value from the local storage
|
|
92
|
+
#
|
|
93
|
+
# #### Parameters
|
|
94
|
+
# - `*args`: an array of strings or symbols that are keys to be removed from the database
|
|
95
|
+
#
|
|
96
|
+
# #### Usage
|
|
97
|
+
#
|
|
98
|
+
# ShopifyCli::DB.del(:admin_access_token)
|
|
99
|
+
#
|
|
100
|
+
def del(*args)
|
|
101
|
+
db.transaction { args.each { |key| db.delete(key) } }
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
# Drops all keys from the database.
|
|
105
|
+
#
|
|
106
|
+
# #### Usage
|
|
107
|
+
#
|
|
108
|
+
# ShopifyCli::DB.clear
|
|
109
|
+
#
|
|
110
|
+
def clear
|
|
111
|
+
del(*keys)
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
require 'shopify_cli'
|
|
2
|
+
|
|
3
|
+
module ShopifyCli
|
|
4
|
+
class Form
|
|
5
|
+
class << self
|
|
6
|
+
def ask(ctx, args, flags)
|
|
7
|
+
attrs = {}
|
|
8
|
+
(@positional_arguments || []).each { |name| attrs[name] = args.shift }
|
|
9
|
+
return nil if attrs.any? { |_k, v| v.nil? }
|
|
10
|
+
(@flag_arguments || []).each { |arg| attrs[arg] = flags[arg] }
|
|
11
|
+
form = new(ctx, args, attrs)
|
|
12
|
+
begin
|
|
13
|
+
form.ask
|
|
14
|
+
form
|
|
15
|
+
rescue ShopifyCli::Abort => err
|
|
16
|
+
ctx.puts(err.message)
|
|
17
|
+
nil
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def positional_arguments(*args)
|
|
22
|
+
@positional_arguments = args
|
|
23
|
+
attr_accessor(*args)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def flag_arguments(*args)
|
|
27
|
+
@flag_arguments = args
|
|
28
|
+
attr_accessor(*args)
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
attr_accessor :ctx, :xargs
|
|
33
|
+
|
|
34
|
+
def initialize(ctx, xargs, attributes)
|
|
35
|
+
@ctx = ctx
|
|
36
|
+
@xargs = xargs
|
|
37
|
+
attributes.each { |k, v| send("#{k}=", v) unless v.nil? }
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
module ShopifyCli
|
|
2
|
+
##
|
|
3
|
+
# ShopifyCli::Git wraps git functionality to make it easier to integrate will
|
|
4
|
+
# git.
|
|
5
|
+
class Git
|
|
6
|
+
class << self
|
|
7
|
+
##
|
|
8
|
+
# will return the current sha of the cli repo
|
|
9
|
+
#
|
|
10
|
+
# #### Parameters
|
|
11
|
+
#
|
|
12
|
+
# * `dir` - the directory of the git repo. This defaults to the cli repo
|
|
13
|
+
# * `ctx` - the current running context of your command
|
|
14
|
+
#
|
|
15
|
+
# #### Returns
|
|
16
|
+
#
|
|
17
|
+
# * `sha_string` - string of the sha of the most recent commit to the repo
|
|
18
|
+
#
|
|
19
|
+
# #### Example
|
|
20
|
+
#
|
|
21
|
+
# ShopifyCli::Git.sha
|
|
22
|
+
#
|
|
23
|
+
def sha(dir: Dir.pwd, ctx: Context.new)
|
|
24
|
+
rev_parse('HEAD', dir: dir, ctx: ctx)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
##
|
|
28
|
+
# will make calls to git to clone a new repo into a supplied destination,
|
|
29
|
+
# it will also output progress of the cloning process.
|
|
30
|
+
#
|
|
31
|
+
# #### Parameters
|
|
32
|
+
#
|
|
33
|
+
# * `repository` - a git url for git to clone the repo from
|
|
34
|
+
# * `dest` - a filepath to where the repo should be cloned to
|
|
35
|
+
# * `ctx` - the current running context of your command, defaults to a new context.
|
|
36
|
+
#
|
|
37
|
+
# #### Returns
|
|
38
|
+
#
|
|
39
|
+
# * `sha_string` - string of the sha of the most recent commit to the repo
|
|
40
|
+
#
|
|
41
|
+
# #### Example
|
|
42
|
+
#
|
|
43
|
+
# ShopifyCli::Git.clone('git@github.com:shopify/test.git', 'test-app')
|
|
44
|
+
#
|
|
45
|
+
def clone(repository, dest, ctx: Context.new)
|
|
46
|
+
if Dir.exist?(dest)
|
|
47
|
+
ctx.abort(ctx.message('core.git.error.directory_exists'))
|
|
48
|
+
else
|
|
49
|
+
CLI::UI::Frame.open(ctx.message('core.git.cloning', dest)) do
|
|
50
|
+
clone_progress('clone', '--single-branch', repository, dest, ctx: ctx)
|
|
51
|
+
end
|
|
52
|
+
ctx.done(ctx.message('core.git.cloned', dest))
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
##
|
|
57
|
+
# will fetch the repos list of branches.
|
|
58
|
+
#
|
|
59
|
+
# #### Parameters
|
|
60
|
+
#
|
|
61
|
+
# * `ctx` - the current running context of your command, defaults to a new context.
|
|
62
|
+
#
|
|
63
|
+
# #### Returns
|
|
64
|
+
#
|
|
65
|
+
# * `branches` - [String] an array of strings that are branch names
|
|
66
|
+
#
|
|
67
|
+
# #### Example
|
|
68
|
+
#
|
|
69
|
+
# branches = ShopifyCli::Git.branches(@ctx)
|
|
70
|
+
#
|
|
71
|
+
def branches(ctx)
|
|
72
|
+
output, status = ctx.capture2e('git', 'branch', '--list', '--format=%(refname:short)')
|
|
73
|
+
ctx.abort(ctx.message('core.git.error.no_branches_found')) unless status.success?
|
|
74
|
+
|
|
75
|
+
branches = if output == ''
|
|
76
|
+
['master']
|
|
77
|
+
else
|
|
78
|
+
output.split("\n")
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
branches
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
##
|
|
85
|
+
# will initialize a new repo in the current directory. This will output
|
|
86
|
+
# if it was successful or not.
|
|
87
|
+
#
|
|
88
|
+
# #### Parameters
|
|
89
|
+
#
|
|
90
|
+
# * `ctx` - the current running context of your command, defaults to a new context.
|
|
91
|
+
#
|
|
92
|
+
# #### Example
|
|
93
|
+
#
|
|
94
|
+
# ShopifyCli::Git.init(@ctx)
|
|
95
|
+
#
|
|
96
|
+
def init(ctx)
|
|
97
|
+
output, status = ctx.capture2e('git', 'status')
|
|
98
|
+
|
|
99
|
+
unless status.success?
|
|
100
|
+
ctx.abort(ctx.message('core.git.error.repo_not_initiated'))
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
if output.include?('No commits yet')
|
|
104
|
+
ctx.abort(ctx.message('core.git.error.no_commits_made'))
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
private
|
|
109
|
+
|
|
110
|
+
def exec(*args, dir: Dir.pwd, default: nil, ctx: Context.new)
|
|
111
|
+
args = %w(git) + args
|
|
112
|
+
out, _, stat = ctx.capture3(*args, chdir: dir)
|
|
113
|
+
return default unless stat.success?
|
|
114
|
+
out.chomp
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def rev_parse(*args, dir: nil, ctx: Context.new)
|
|
118
|
+
exec('rev-parse', *args, dir: dir, ctx: ctx)
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
def clone_progress(*git_command, ctx:)
|
|
122
|
+
CLI::UI::Progress.progress do |bar|
|
|
123
|
+
msg = []
|
|
124
|
+
success = ctx.system('git', *git_command, '--progress') do |_out, err|
|
|
125
|
+
if err.strip.start_with?('Receiving objects:')
|
|
126
|
+
percent = (err.match(/Receiving objects:\s+(\d+)/)[1].to_f / 100).round(2)
|
|
127
|
+
bar.tick(set_percent: percent)
|
|
128
|
+
next
|
|
129
|
+
end
|
|
130
|
+
msg << err
|
|
131
|
+
end.success?
|
|
132
|
+
unless success
|
|
133
|
+
ctx.abort(msg.join("\n"))
|
|
134
|
+
end
|
|
135
|
+
bar.tick(set_percent: 1.0)
|
|
136
|
+
true
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
end
|
|
141
|
+
end
|