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,32 @@
|
|
|
1
|
+
module ShopifyCli
|
|
2
|
+
class PartnersAPI
|
|
3
|
+
class Organizations
|
|
4
|
+
class << self
|
|
5
|
+
def fetch_all(ctx)
|
|
6
|
+
resp = PartnersAPI.query(ctx, 'all_organizations')
|
|
7
|
+
resp['data']['organizations']['nodes'].map do |org|
|
|
8
|
+
org['stores'] = org['stores']['nodes']
|
|
9
|
+
org
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def fetch(ctx, id:)
|
|
14
|
+
resp = PartnersAPI.query(ctx, 'find_organization', id: id)
|
|
15
|
+
org = resp['data']['organizations']['nodes'].first
|
|
16
|
+
return nil if org.nil?
|
|
17
|
+
org['stores'] = org['stores']['nodes']
|
|
18
|
+
org
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def fetch_with_app(ctx)
|
|
22
|
+
resp = PartnersAPI.query(ctx, 'all_orgs_with_apps')
|
|
23
|
+
resp['data']['organizations']['nodes'].map do |org|
|
|
24
|
+
org['stores'] = org['stores']['nodes']
|
|
25
|
+
org['apps'] = org['apps']['nodes']
|
|
26
|
+
org
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
require 'fileutils'
|
|
2
|
+
|
|
3
|
+
module ShopifyCli
|
|
4
|
+
##
|
|
5
|
+
# ProcessSupervision wraps a running process spawned by `exec` and keeps track
|
|
6
|
+
# if its `pid` and keeps a log file for it as well
|
|
7
|
+
class ProcessSupervision
|
|
8
|
+
# is the directory where the pid and logfile are kept
|
|
9
|
+
RUN_DIR = File.join(ShopifyCli::CACHE_DIR, 'sv')
|
|
10
|
+
|
|
11
|
+
# a string or a symbol to identify this process by
|
|
12
|
+
attr_reader :identifier
|
|
13
|
+
# process ID for the running process
|
|
14
|
+
attr_reader :pid
|
|
15
|
+
# starttime of the process
|
|
16
|
+
attr_reader :time
|
|
17
|
+
# filepath to the pidfile for this process
|
|
18
|
+
attr_reader :pid_path
|
|
19
|
+
# filepath to the logfile for this process
|
|
20
|
+
attr_reader :log_path
|
|
21
|
+
|
|
22
|
+
class << self
|
|
23
|
+
##
|
|
24
|
+
# Will find and create a new instance of ProcessSupervision for a running process
|
|
25
|
+
# if it is currently running. It will return nil if the process is not running.
|
|
26
|
+
#
|
|
27
|
+
# #### Parameters
|
|
28
|
+
#
|
|
29
|
+
# * `identifier` - a string or a symbol that a process was started with
|
|
30
|
+
#
|
|
31
|
+
# #### Returns
|
|
32
|
+
#
|
|
33
|
+
# * `process` - ProcessSupervision instance if the process is running this
|
|
34
|
+
# will be nil if the process is not running.
|
|
35
|
+
#
|
|
36
|
+
def for_ident(identifier)
|
|
37
|
+
pid, time = File.read(File.join(RUN_DIR, "#{identifier}.pid")).split(':')
|
|
38
|
+
new(identifier, pid: Integer(pid), time: time)
|
|
39
|
+
rescue Errno::ENOENT
|
|
40
|
+
nil
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
##
|
|
44
|
+
# will fork and spawn a new process that is separate from the current process.
|
|
45
|
+
# This process will keep running beyond the command running so be careful!
|
|
46
|
+
#
|
|
47
|
+
# #### Parameters
|
|
48
|
+
#
|
|
49
|
+
# * `identifier` - a string or symbol to identify the new process by.
|
|
50
|
+
# * `args` - a command to run, either a string or array of strings
|
|
51
|
+
#
|
|
52
|
+
# #### Returns
|
|
53
|
+
#
|
|
54
|
+
# * `process` - ProcessSupervision instance if the process is running, this
|
|
55
|
+
# will be nil if the process did not start.
|
|
56
|
+
#
|
|
57
|
+
def start(identifier, args)
|
|
58
|
+
return for_ident(identifier) if running?(identifier)
|
|
59
|
+
fork do
|
|
60
|
+
pid_file = new(identifier, pid: Process.pid)
|
|
61
|
+
pid_file.write
|
|
62
|
+
STDOUT.reopen(pid_file.log_path, "w")
|
|
63
|
+
STDERR.reopen(pid_file.log_path, "w")
|
|
64
|
+
STDIN.reopen("/dev/null", "r")
|
|
65
|
+
Process.setsid
|
|
66
|
+
exec(*args)
|
|
67
|
+
end
|
|
68
|
+
sleep(0.1)
|
|
69
|
+
for_ident(identifier)
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
##
|
|
73
|
+
# will attempt to shutdown a running process
|
|
74
|
+
#
|
|
75
|
+
# #### Parameters
|
|
76
|
+
#
|
|
77
|
+
# * `identifier` - a string or symbol to identify the new process by.
|
|
78
|
+
#
|
|
79
|
+
# #### Returns
|
|
80
|
+
#
|
|
81
|
+
# * `stopped` - [true, false]
|
|
82
|
+
#
|
|
83
|
+
def stop(identifier)
|
|
84
|
+
process = for_ident(identifier)
|
|
85
|
+
return false unless process
|
|
86
|
+
process.stop
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
##
|
|
90
|
+
# will help identify if your process is still running in the background.
|
|
91
|
+
#
|
|
92
|
+
# #### Parameters
|
|
93
|
+
#
|
|
94
|
+
# * `identifier` - a string or symbol to identify the new process by.
|
|
95
|
+
#
|
|
96
|
+
# #### Returns
|
|
97
|
+
#
|
|
98
|
+
# * `running` - [true, false]
|
|
99
|
+
#
|
|
100
|
+
def running?(identifier)
|
|
101
|
+
process = for_ident(identifier)
|
|
102
|
+
return false unless process
|
|
103
|
+
process.alive?
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def initialize(identifier, pid:, time: Time.now.strftime('%s')) # :nodoc:
|
|
108
|
+
@identifier = identifier
|
|
109
|
+
@pid = pid
|
|
110
|
+
@time = time
|
|
111
|
+
@pid_path = File.join(RUN_DIR, "#{identifier}.pid")
|
|
112
|
+
@log_path = File.join(RUN_DIR, "#{identifier}.log")
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
##
|
|
116
|
+
# will attempt to shutdown a running process
|
|
117
|
+
#
|
|
118
|
+
# #### Returns
|
|
119
|
+
#
|
|
120
|
+
# * `stopped` - [true, false]
|
|
121
|
+
#
|
|
122
|
+
def stop
|
|
123
|
+
unlink
|
|
124
|
+
kill_proc
|
|
125
|
+
true
|
|
126
|
+
rescue
|
|
127
|
+
false
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
##
|
|
131
|
+
# will help identify if your process is still running in the background.
|
|
132
|
+
#
|
|
133
|
+
# #### Returns
|
|
134
|
+
#
|
|
135
|
+
# * `alive` - [true, false]
|
|
136
|
+
#
|
|
137
|
+
def alive?
|
|
138
|
+
stat(pid)
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
##
|
|
142
|
+
# persists the pidfile
|
|
143
|
+
#
|
|
144
|
+
def write
|
|
145
|
+
FileUtils.mkdir_p(File.dirname(pid_path))
|
|
146
|
+
File.write(pid_path, "#{pid}:#{time}")
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
private
|
|
150
|
+
|
|
151
|
+
def unlink
|
|
152
|
+
File.unlink(pid_path)
|
|
153
|
+
File.unlink(log_path)
|
|
154
|
+
nil
|
|
155
|
+
rescue Errno::ENOENT
|
|
156
|
+
nil
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
def kill_proc
|
|
160
|
+
kill(-pid) # process group
|
|
161
|
+
rescue Errno::ESRCH
|
|
162
|
+
begin
|
|
163
|
+
kill(pid)
|
|
164
|
+
rescue Errno::ESRCH # The process group does not exist, try the pid itself
|
|
165
|
+
# Race condition, process died in the middle
|
|
166
|
+
end
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
def kill(id)
|
|
170
|
+
Process.kill('TERM', id)
|
|
171
|
+
50.times do
|
|
172
|
+
sleep 0.1
|
|
173
|
+
break unless stat(id)
|
|
174
|
+
end
|
|
175
|
+
Process.kill('KILL', id) if stat(id)
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
def stat(id)
|
|
179
|
+
Process.kill(0, id) # signal 0 checks if pid is alive
|
|
180
|
+
true
|
|
181
|
+
rescue Errno::EPERM
|
|
182
|
+
true
|
|
183
|
+
rescue Errno::ESRCH
|
|
184
|
+
false
|
|
185
|
+
end
|
|
186
|
+
end
|
|
187
|
+
end
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
require 'shopify_cli'
|
|
3
|
+
|
|
4
|
+
module ShopifyCli
|
|
5
|
+
##
|
|
6
|
+
# ShopifyCli::Project captures the current project that the user is working on.
|
|
7
|
+
# This class can be used to fetch and save project environment as well as the
|
|
8
|
+
# project config `.shopify-cli.yml`.
|
|
9
|
+
#
|
|
10
|
+
class Project
|
|
11
|
+
include SmartProperties
|
|
12
|
+
|
|
13
|
+
class << self
|
|
14
|
+
##
|
|
15
|
+
# will get an instance of the project that the user is currently operating
|
|
16
|
+
# on. This is used for access to project resources.
|
|
17
|
+
#
|
|
18
|
+
# #### Returns
|
|
19
|
+
#
|
|
20
|
+
# * `project` - a Project instance if the user is currently in the project.
|
|
21
|
+
#
|
|
22
|
+
# #### Raises
|
|
23
|
+
#
|
|
24
|
+
# * `ShopifyCli::Abort` - If the cli is not currently in a project directory
|
|
25
|
+
# then this will be raised with a message implying that the user is not in
|
|
26
|
+
# a project directory.
|
|
27
|
+
#
|
|
28
|
+
# #### Example
|
|
29
|
+
#
|
|
30
|
+
# project = ShopifyCli::Project.current
|
|
31
|
+
#
|
|
32
|
+
def current
|
|
33
|
+
at(Dir.pwd)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
##
|
|
37
|
+
# will return true if the command line is currently within a project
|
|
38
|
+
#
|
|
39
|
+
# #### Returns
|
|
40
|
+
#
|
|
41
|
+
# * `has_current?` - boolean, true if there is a current project
|
|
42
|
+
#
|
|
43
|
+
def has_current?
|
|
44
|
+
!directory(Dir.pwd).nil?
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
##
|
|
48
|
+
# will fetch the project type of the current project. This is mostly used
|
|
49
|
+
# for internal project type loading, you should not normally need this.
|
|
50
|
+
#
|
|
51
|
+
# #### Returns
|
|
52
|
+
#
|
|
53
|
+
# * `type` - a symbol of the name of the project type identifier. i.e. [rails, node]
|
|
54
|
+
# This will be nil if the user is not in a current project.
|
|
55
|
+
#
|
|
56
|
+
# #### Example
|
|
57
|
+
#
|
|
58
|
+
# type = ShopifyCli::Project.current_project_type
|
|
59
|
+
#
|
|
60
|
+
def current_project_type
|
|
61
|
+
return unless has_current?
|
|
62
|
+
current.config['project_type'].to_sym
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
##
|
|
66
|
+
# writes out the `.shopify-cli.yml` file. You should use this when creating
|
|
67
|
+
# a project type so that the rest of your project type commands will load
|
|
68
|
+
# in this project, in the future.
|
|
69
|
+
#
|
|
70
|
+
# #### Parameters
|
|
71
|
+
#
|
|
72
|
+
# * `ctx` - the current running context of your command
|
|
73
|
+
# * `project_type` - a string or symbol of your project type name
|
|
74
|
+
# * `organization_id` - the id of the partner organization that the app is owned by. Used for metrics
|
|
75
|
+
# * `identifiers` - an optional hash of other app identifiers
|
|
76
|
+
#
|
|
77
|
+
# #### Example
|
|
78
|
+
#
|
|
79
|
+
# type = ShopifyCli::Project.current_project_type
|
|
80
|
+
#
|
|
81
|
+
def write(ctx, project_type:, organization_id:, **identifiers)
|
|
82
|
+
require 'yaml' # takes 20ms, so deferred as late as possible.
|
|
83
|
+
content = Hash[{ project_type: project_type, organization_id: organization_id.to_i }
|
|
84
|
+
.merge(identifiers)
|
|
85
|
+
.collect { |k, v| [k.to_s, v] }]
|
|
86
|
+
|
|
87
|
+
ctx.write('.shopify-cli.yml', YAML.dump(content))
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def project_name
|
|
91
|
+
File.basename(current.directory)
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
private
|
|
95
|
+
|
|
96
|
+
def directory(dir)
|
|
97
|
+
@dir ||= Hash.new { |h, k| h[k] = __directory(k) }
|
|
98
|
+
@dir[dir]
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def at(dir)
|
|
102
|
+
proj_dir = directory(dir)
|
|
103
|
+
unless proj_dir
|
|
104
|
+
raise(ShopifyCli::Abort, Context.message('core.project.error.not_in_project'))
|
|
105
|
+
end
|
|
106
|
+
@at ||= Hash.new { |h, k| h[k] = new(directory: k) }
|
|
107
|
+
@at[proj_dir]
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def __directory(curr)
|
|
111
|
+
loop do
|
|
112
|
+
return nil if curr == '/'
|
|
113
|
+
file = File.join(curr, '.shopify-cli.yml')
|
|
114
|
+
return curr if File.exist?(file)
|
|
115
|
+
curr = File.dirname(curr)
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
property :directory # :nodoc:
|
|
121
|
+
|
|
122
|
+
##
|
|
123
|
+
# will read, parse and return the envfile for the project
|
|
124
|
+
#
|
|
125
|
+
# #### Returns
|
|
126
|
+
#
|
|
127
|
+
# * `env` - An instance of a ShopifyCli::Resources::EnvFile
|
|
128
|
+
#
|
|
129
|
+
# #### Example
|
|
130
|
+
#
|
|
131
|
+
# ShopifyCli::Project.current.env
|
|
132
|
+
#
|
|
133
|
+
def env
|
|
134
|
+
@env ||= begin
|
|
135
|
+
Resources::EnvFile.read(directory)
|
|
136
|
+
rescue Errno::ENOENT
|
|
137
|
+
nil
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
##
|
|
142
|
+
# will read, parse and return the .shopify-cli.yml for the project
|
|
143
|
+
#
|
|
144
|
+
# #### Returns
|
|
145
|
+
#
|
|
146
|
+
# * `config` - A hash of configuration
|
|
147
|
+
#
|
|
148
|
+
# #### Raises
|
|
149
|
+
#
|
|
150
|
+
# * `ShopifyCli::Abort` - If the yml is invalid or poorly formatted
|
|
151
|
+
# * `ShopifyCli::Abort` - If the yml file does not exist
|
|
152
|
+
#
|
|
153
|
+
# #### Example
|
|
154
|
+
#
|
|
155
|
+
# ShopifyCli::Project.current.config
|
|
156
|
+
#
|
|
157
|
+
def config
|
|
158
|
+
@config ||= begin
|
|
159
|
+
config = load_yaml_file('.shopify-cli.yml')
|
|
160
|
+
unless config.is_a?(Hash)
|
|
161
|
+
raise ShopifyCli::Abort, Context.message('core.project.error.cli_yaml.not_hash')
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
# The app_type key was deprecated in favour of project_type, so replace it
|
|
165
|
+
if config.key?('app_type')
|
|
166
|
+
config['project_type'] = config['app_type']
|
|
167
|
+
config.delete('app_type')
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
config
|
|
171
|
+
end
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
private
|
|
175
|
+
|
|
176
|
+
def load_yaml_file(relative_path)
|
|
177
|
+
f = File.join(directory, relative_path)
|
|
178
|
+
require 'yaml' # takes 20ms, so deferred as late as possible.
|
|
179
|
+
begin
|
|
180
|
+
YAML.load_file(f)
|
|
181
|
+
rescue Psych::SyntaxError => e
|
|
182
|
+
raise(ShopifyCli::Abort, Context.message('core.project.error.cli_yaml.invalid', relative_path, e.message))
|
|
183
|
+
# rescue Errno::EACCES => e
|
|
184
|
+
# TODO
|
|
185
|
+
# Dev::Helpers::EaccesHandler.diagnose_and_raise(f, e, mode: :read)
|
|
186
|
+
rescue Errno::ENOENT
|
|
187
|
+
raise ShopifyCli::Abort, Context.message('core.project.error.cli_yaml.not_found', f)
|
|
188
|
+
end
|
|
189
|
+
end
|
|
190
|
+
end
|
|
191
|
+
end
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
module ShopifyCli
|
|
2
|
+
class ProjectType
|
|
3
|
+
class << self
|
|
4
|
+
attr_accessor :project_type,
|
|
5
|
+
:project_name,
|
|
6
|
+
:project_creator_command_class,
|
|
7
|
+
:project_load_shallow
|
|
8
|
+
attr_reader :hidden
|
|
9
|
+
|
|
10
|
+
def repository
|
|
11
|
+
@repository ||= []
|
|
12
|
+
end
|
|
13
|
+
alias_method :all_loaded, :repository
|
|
14
|
+
|
|
15
|
+
def inherited(klass)
|
|
16
|
+
repository << klass
|
|
17
|
+
klass.project_type = @current_type
|
|
18
|
+
klass.project_load_shallow = @shallow_load
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def load_type(current_type, shallow = false)
|
|
22
|
+
filepath = File.join(ShopifyCli::ROOT, 'lib', 'project_types', current_type.to_s, 'cli.rb')
|
|
23
|
+
return unless File.exist?(filepath)
|
|
24
|
+
@shallow_load = shallow
|
|
25
|
+
@current_type = current_type
|
|
26
|
+
load(filepath)
|
|
27
|
+
@current_type = nil
|
|
28
|
+
@shallow_load = false
|
|
29
|
+
for_app_type(current_type)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def load_all
|
|
33
|
+
Dir.glob(File.join(ShopifyCli::ROOT, 'lib', 'project_types', '*', 'cli.rb')).map do |filepath|
|
|
34
|
+
load_type(filepath.split(File::Separator)[-2], true)
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def for_app_type(type)
|
|
39
|
+
repository.find { |k| k.project_type.to_s == type.to_s }
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def project_filepath(path)
|
|
43
|
+
File.join(ShopifyCli::PROJECT_TYPES_DIR, project_type.to_s, path)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def creator(name, command_const)
|
|
47
|
+
@project_name = name
|
|
48
|
+
@project_creator_command_class = command_const
|
|
49
|
+
ShopifyCli::Commands::Create.subcommand(command_const, @project_type)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def create_command
|
|
53
|
+
const_get(@project_creator_command_class)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def hidden_project_type
|
|
57
|
+
@hidden = true
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def register_command(const, cmd)
|
|
61
|
+
return if project_load_shallow
|
|
62
|
+
Context.new.abort(
|
|
63
|
+
Context.message('core.project_type.error.cannot_override_core', cmd, const)
|
|
64
|
+
) if Commands.core_command?(cmd)
|
|
65
|
+
Commands.register(const, cmd)
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def register_task(task, name)
|
|
69
|
+
return if project_load_shallow
|
|
70
|
+
Task::Registry.add(const_get(task), name)
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def register_messages(messages)
|
|
74
|
+
# Make sure we don't attempt to register a file more than once as that will fail
|
|
75
|
+
@registered_message_files ||= {}
|
|
76
|
+
return if @registered_message_files.key?(@project_type)
|
|
77
|
+
@registered_message_files[@project_type] = true
|
|
78
|
+
|
|
79
|
+
Context.load_messages(messages)
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|