shopify-cli 2.6.2 → 2.6.6
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 +4 -4
- data/.github/PULL_REQUEST_TEMPLATE.md +15 -4
- data/.github/workflows/shopify.yml +3 -6
- data/CHANGELOG.md +89 -99
- data/CONTRIBUTING.md +9 -1
- data/Dockerfile +22 -4
- data/Gemfile +2 -0
- data/Gemfile.lock +7 -3
- data/RELEASING.md +17 -30
- data/Rakefile +0 -5
- data/lib/project_types/extension/cli.rb +1 -0
- data/lib/project_types/extension/commands/create.rb +1 -0
- data/lib/project_types/extension/features/argo.rb +9 -10
- data/lib/project_types/extension/features/argo_serve.rb +1 -1
- data/lib/project_types/extension/forms/create.rb +1 -1
- data/lib/project_types/extension/forms/questions/ask_template.rb +2 -1
- data/lib/project_types/extension/messages/messages.rb +1 -0
- data/lib/project_types/extension/models/server_config/extension.rb +2 -0
- data/lib/project_types/extension/models/specification_handlers/checkout_post_purchase.rb +1 -1
- data/lib/project_types/extension/models/specification_handlers/checkout_ui_extension.rb +1 -1
- data/lib/project_types/extension/tasks/converters/server_config_converter.rb +4 -5
- data/lib/project_types/extension/tasks/find_package_from_json.rb +37 -0
- data/lib/project_types/extension/tasks/load_server_config.rb +6 -1
- data/lib/project_types/node/commands/serve.rb +7 -16
- data/lib/project_types/node/messages/messages.rb +0 -5
- data/lib/project_types/php/commands/serve.rb +6 -9
- data/lib/project_types/php/messages/messages.rb +1 -4
- data/lib/project_types/rails/commands/create.rb +45 -16
- data/lib/project_types/rails/commands/serve.rb +7 -8
- data/lib/project_types/rails/forms/create.rb +0 -1
- data/lib/project_types/rails/messages/messages.rb +1 -4
- data/lib/project_types/script/commands/create.rb +4 -5
- data/lib/project_types/script/config/extension_points.yml +10 -0
- data/lib/project_types/script/errors.rb +0 -18
- data/lib/project_types/script/graphql/app_script_set.graphql +2 -0
- data/lib/project_types/script/layers/application/build_script.rb +2 -1
- data/lib/project_types/script/layers/application/create_script.rb +2 -2
- data/lib/project_types/script/layers/application/push_script.rb +15 -1
- data/lib/project_types/script/layers/domain/push_package.rb +5 -2
- data/lib/project_types/script/layers/domain/script_json.rb +1 -1
- data/lib/project_types/script/layers/infrastructure/api_clients/partners_proxy_api_client.rb +0 -4
- data/lib/project_types/script/layers/infrastructure/errors.rb +17 -2
- data/lib/project_types/script/layers/infrastructure/languages/assemblyscript_task_runner.rb +29 -13
- data/lib/project_types/script/layers/infrastructure/languages/typescript_task_runner.rb +29 -13
- data/lib/project_types/script/layers/infrastructure/push_package_repository.rb +4 -2
- data/lib/project_types/script/layers/infrastructure/script_project_repository.rb +3 -4
- data/lib/project_types/script/layers/infrastructure/script_service.rb +7 -2
- data/lib/project_types/script/messages/messages.rb +9 -22
- data/lib/project_types/script/ui/error_handler.rb +16 -26
- data/lib/project_types/theme/commands/serve.rb +2 -0
- data/lib/project_types/theme/messages/messages.rb +6 -0
- data/lib/shopify_cli/app_type_detector.rb +32 -0
- data/lib/shopify_cli/command.rb +6 -1
- data/lib/shopify_cli/command_options/command_serve_options.rb +43 -0
- data/lib/shopify_cli/command_options.rb +7 -0
- data/lib/shopify_cli/commands/login.rb +3 -3
- data/lib/shopify_cli/commands/reporting.rb +38 -0
- data/lib/shopify_cli/commands/switch.rb +1 -1
- data/lib/shopify_cli/commands.rb +1 -0
- data/lib/shopify_cli/constants.rb +7 -3
- data/lib/shopify_cli/core/monorail.rb +9 -20
- data/lib/shopify_cli/environment.rb +15 -1
- data/lib/shopify_cli/exception_reporter.rb +29 -15
- data/lib/shopify_cli/messages/messages.rb +48 -19
- data/lib/shopify_cli/migrator/migration.rb +1 -1
- data/lib/shopify_cli/migrator/migrations/1631709766_noop.rb +1 -1
- data/lib/shopify_cli/migrator/migrations/1633691650_merge_reporting_configuration.rb +41 -0
- data/lib/shopify_cli/migrator.rb +9 -11
- data/lib/shopify_cli/reporting_configuration_controller.rb +64 -0
- data/lib/shopify_cli/services/base_service.rb +13 -0
- data/lib/shopify_cli/services/reporting_service.rb +16 -0
- data/lib/shopify_cli/services.rb +6 -0
- data/lib/shopify_cli/theme/dev_server/watcher.rb +2 -2
- data/lib/shopify_cli/theme/dev_server.rb +3 -2
- data/lib/shopify_cli/version.rb +1 -1
- data/lib/shopify_cli.rb +4 -0
- data/shopify-cli.gemspec +2 -13
- data/utilities/docker/container.rb +97 -0
- data/utilities/docker.rb +45 -3
- metadata +18 -10
- data/ext/shopify-cli/extconf.rb +0 -60
- data/lib/project_types/script/graphql/app_script_update_or_create.graphql +0 -0
- data/lib/shopify_cli/exception_reporter/permission_controller.rb +0 -54
| @@ -16,9 +16,6 @@ module ShopifyCLI | |
| 16 16 | 
             
                    attr_accessor :metadata
         | 
| 17 17 |  | 
| 18 18 | 
             
                    def log(name, args, &block) # rubocop:disable Lint/UnusedMethodArgument
         | 
| 19 | 
            -
                      prompt_for_consent
         | 
| 20 | 
            -
                      return yield unless enabled? && consented?
         | 
| 21 | 
            -
             | 
| 22 19 | 
             
                      command, command_name = Commands::Registry.lookup_command(name)
         | 
| 23 20 | 
             
                      final_command = [command_name]
         | 
| 24 21 | 
             
                      if command
         | 
| @@ -28,13 +25,18 @@ module ShopifyCLI | |
| 28 25 |  | 
| 29 26 | 
             
                      start_time = now_in_milliseconds
         | 
| 30 27 | 
             
                      err = nil
         | 
| 28 | 
            +
             | 
| 31 29 | 
             
                      begin
         | 
| 32 30 | 
             
                        yield
         | 
| 33 31 | 
             
                      rescue Exception => e # rubocop:disable Lint/RescueException
         | 
| 34 32 | 
             
                        err = e
         | 
| 35 33 | 
             
                        raise
         | 
| 36 34 | 
             
                      ensure
         | 
| 37 | 
            -
                         | 
| 35 | 
            +
                        # If there's an error, we don't prompt from here and we let the exception
         | 
| 36 | 
            +
                        # reporter do that.
         | 
| 37 | 
            +
                        if report?(prompt: err.nil?)
         | 
| 38 | 
            +
                          send_event(start_time, final_command, args - final_command, err&.message)
         | 
| 39 | 
            +
                        end
         | 
| 38 40 | 
             
                      end
         | 
| 39 41 | 
             
                    end
         | 
| 40 42 |  | 
| @@ -44,22 +46,9 @@ module ShopifyCLI | |
| 44 46 | 
             
                      (Time.now.utc.to_f * 1000).to_i
         | 
| 45 47 | 
             
                    end
         | 
| 46 48 |  | 
| 47 | 
            -
                     | 
| 48 | 
            -
             | 
| 49 | 
            -
                      ( | 
| 50 | 
            -
                    end
         | 
| 51 | 
            -
             | 
| 52 | 
            -
                    def consented?
         | 
| 53 | 
            -
                      ShopifyCLI::Config.get_bool("analytics", "enabled")
         | 
| 54 | 
            -
                    end
         | 
| 55 | 
            -
             | 
| 56 | 
            -
                    def prompt_for_consent
         | 
| 57 | 
            -
                      return if Context.new.ci?
         | 
| 58 | 
            -
                      return unless enabled?
         | 
| 59 | 
            -
                      return if ShopifyCLI::Config.get_section("analytics").key?("enabled")
         | 
| 60 | 
            -
                      msg = Context.message("core.monorail.consent_prompt")
         | 
| 61 | 
            -
                      opt = CLI::UI::Prompt.confirm(msg)
         | 
| 62 | 
            -
                      ShopifyCLI::Config.set("analytics", "enabled", opt)
         | 
| 49 | 
            +
                    def report?(prompt:)
         | 
| 50 | 
            +
                      return true if Environment.send_monorail_events?
         | 
| 51 | 
            +
                      ReportingConfigurationController.check_or_prompt_report_automatically(source: :usage, prompt: prompt)
         | 
| 63 52 | 
             
                    end
         | 
| 64 53 |  | 
| 65 54 | 
             
                    def send_event(start_time, commands, args, err = nil)
         | 
| @@ -26,7 +26,7 @@ module ShopifyCLI | |
| 26 26 | 
             
                  env_variable_truthy?(
         | 
| 27 27 | 
             
                    Constants::EnvironmentVariables::STACKTRACE,
         | 
| 28 28 | 
             
                    env_variables: env_variables
         | 
| 29 | 
            -
                  )
         | 
| 29 | 
            +
                  ) || development?(env_variables: env_variables)
         | 
| 30 30 | 
             
                end
         | 
| 31 31 |  | 
| 32 32 | 
             
                def self.test?(env_variables: ENV)
         | 
| @@ -36,6 +36,13 @@ module ShopifyCLI | |
| 36 36 | 
             
                  )
         | 
| 37 37 | 
             
                end
         | 
| 38 38 |  | 
| 39 | 
            +
                def self.acceptance_test?(env_variables: ENV)
         | 
| 40 | 
            +
                  env_variable_truthy?(
         | 
| 41 | 
            +
                    Constants::EnvironmentVariables::ACCEPTANCE_TEST,
         | 
| 42 | 
            +
                    env_variables: env_variables
         | 
| 43 | 
            +
                  )
         | 
| 44 | 
            +
                end
         | 
| 45 | 
            +
             | 
| 39 46 | 
             
                def self.print_backtrace?(env_variables: ENV)
         | 
| 40 47 | 
             
                  env_variable_truthy?(
         | 
| 41 48 | 
             
                    Constants::EnvironmentVariables::BACKTRACE,
         | 
| @@ -72,6 +79,13 @@ module ShopifyCLI | |
| 72 79 | 
             
                  "#{spin_workspace}.#{spin_namespace}.#{spin_host}"
         | 
| 73 80 | 
             
                end
         | 
| 74 81 |  | 
| 82 | 
            +
                def self.send_monorail_events?(env_variables: ENV)
         | 
| 83 | 
            +
                  env_variable_truthy?(
         | 
| 84 | 
            +
                    Constants::EnvironmentVariables::MONORAIL_REAL_EVENTS,
         | 
| 85 | 
            +
                    env_variables: env_variables
         | 
| 86 | 
            +
                  )
         | 
| 87 | 
            +
                end
         | 
| 88 | 
            +
             | 
| 75 89 | 
             
                def self.env_variable_truthy?(variable_name, env_variables: ENV)
         | 
| 76 90 | 
             
                  TRUTHY_ENV_VARIABLE_VALUES.include?(env_variables[variable_name.to_s])
         | 
| 77 91 | 
             
                end
         | 
| @@ -1,20 +1,23 @@ | |
| 1 1 | 
             
            module ShopifyCLI
         | 
| 2 2 | 
             
              module ExceptionReporter
         | 
| 3 | 
            -
                autoload :PermissionController, "shopify_cli/exception_reporter/permission_controller"
         | 
| 4 | 
            -
             | 
| 5 3 | 
             
                def self.report(error, _logs = nil, _api_key = nil, custom_metadata = {})
         | 
| 6 4 | 
             
                  context = ShopifyCLI::Context.new
         | 
| 7 | 
            -
             | 
| 8 | 
            -
                   | 
| 9 | 
            -
             | 
| 5 | 
            +
             | 
| 6 | 
            +
                  unless ShopifyCLI::Environment.development?
         | 
| 7 | 
            +
                    context.puts(context.message("core.error_reporting.unhandled_error.message"))
         | 
| 8 | 
            +
                    context.puts(context.message("core.error_reporting.unhandled_error.issue_message"))
         | 
| 9 | 
            +
                  end
         | 
| 10 | 
            +
             | 
| 11 | 
            +
                  # Stack trace hint
         | 
| 10 12 | 
             
                  unless ShopifyCLI::Environment.print_stacktrace?
         | 
| 11 13 | 
             
                    context.puts(context.message("core.error_reporting.unhandled_error.stacktrace_message",
         | 
| 12 14 | 
             
                      "#{ShopifyCLI::Constants::EnvironmentVariables::STACKTRACE}=1"))
         | 
| 13 15 | 
             
                  end
         | 
| 16 | 
            +
             | 
| 14 17 | 
             
                  context.puts("\n")
         | 
| 15 18 |  | 
| 16 19 | 
             
                  return unless reportable_error?(error)
         | 
| 17 | 
            -
                  return unless report?
         | 
| 20 | 
            +
                  return unless report?(context: context)
         | 
| 18 21 |  | 
| 19 22 | 
             
                  ENV["BUGSNAG_DISABLE_AUTOCONFIGURE"] = "1"
         | 
| 20 23 | 
             
                  require "bugsnag"
         | 
| @@ -28,25 +31,36 @@ module ShopifyCLI | |
| 28 31 | 
             
                    config.auto_capture_sessions = false
         | 
| 29 32 | 
             
                  end
         | 
| 30 33 |  | 
| 31 | 
            -
                  metadata = {}
         | 
| 34 | 
            +
                  metadata = { rubyPlatform: RUBY_PLATFORM }
         | 
| 32 35 | 
             
                  metadata.merge!(custom_metadata)
         | 
| 33 | 
            -
             | 
| 36 | 
            +
             | 
| 37 | 
            +
                  Bugsnag.notify(error) do |event|
         | 
| 38 | 
            +
                    event.add_metadata(:device, metadata)
         | 
| 39 | 
            +
                  end
         | 
| 34 40 | 
             
                end
         | 
| 35 41 |  | 
| 36 | 
            -
                def self.report?
         | 
| 37 | 
            -
                   | 
| 38 | 
            -
             | 
| 39 | 
            -
                    ExceptionReporter::PermissionController.can_report_automatically?
         | 
| 42 | 
            +
                def self.report?(context:)
         | 
| 43 | 
            +
                  return true if ReportingConfigurationController.reporting_prompted? &&
         | 
| 44 | 
            +
                    ReportingConfigurationController.check_or_prompt_report_automatically(source: :uncaught_error)
         | 
| 40 45 |  | 
| 41 | 
            -
                  report_error =  | 
| 46 | 
            +
                  report_error = report_error?(context: context)
         | 
| 42 47 |  | 
| 43 | 
            -
                  unless  | 
| 44 | 
            -
                     | 
| 48 | 
            +
                  unless ReportingConfigurationController.reporting_prompted?
         | 
| 49 | 
            +
                    ReportingConfigurationController.check_or_prompt_report_automatically(source: :uncaught_error)
         | 
| 45 50 | 
             
                  end
         | 
| 46 51 |  | 
| 47 52 | 
             
                  report_error
         | 
| 48 53 | 
             
                end
         | 
| 49 54 |  | 
| 55 | 
            +
                def self.report_error?(context:)
         | 
| 56 | 
            +
                  return false if Environment.development?
         | 
| 57 | 
            +
             | 
| 58 | 
            +
                  CLI::UI::Prompt.ask(context.message("core.error_reporting.report_error.question")) do |handler|
         | 
| 59 | 
            +
                    handler.option(context.message("core.error_reporting.report_error.yes")) { |_| true }
         | 
| 60 | 
            +
                    handler.option(context.message("core.error_reporting.report_error.no")) { |_| false }
         | 
| 61 | 
            +
                  end
         | 
| 62 | 
            +
                end
         | 
| 63 | 
            +
             | 
| 50 64 | 
             
                def self.reportable_error?(error)
         | 
| 51 65 | 
             
                  is_abort = error.is_a?(ShopifyCLI::Abort) || error.is_a?(ShopifyCLI::AbortSilent)
         | 
| 52 66 | 
             
                  !is_abort
         | 
| @@ -14,6 +14,18 @@ module ShopifyCLI | |
| 14 14 | 
             
                    },
         | 
| 15 15 | 
             
                  },
         | 
| 16 16 | 
             
                  core: {
         | 
| 17 | 
            +
                    app: {
         | 
| 18 | 
            +
                      serve: {
         | 
| 19 | 
            +
                        error: {
         | 
| 20 | 
            +
                          invalid_port: "%s is not a valid port.",
         | 
| 21 | 
            +
                          host_must_be_https: "HOST must be a HTTPS url.",
         | 
| 22 | 
            +
                        },
         | 
| 23 | 
            +
                      },
         | 
| 24 | 
            +
                      help: <<~HELP,
         | 
| 25 | 
            +
                      Create and manage embedded apps
         | 
| 26 | 
            +
                        Usage: {{command:%s app [ rails | node | php ] }}
         | 
| 27 | 
            +
                      HELP
         | 
| 28 | 
            +
                    },
         | 
| 17 29 | 
             
                    error_reporting: {
         | 
| 18 30 | 
             
                      unhandled_error: {
         | 
| 19 31 | 
             
                        message: "{{x}} {{red:An unexpected error occured.}}",
         | 
| @@ -21,16 +33,25 @@ module ShopifyCLI | |
| 21 33 | 
             
                          " include the stack trace.}}",
         | 
| 22 34 | 
             
                        stacktrace_message: "{{red:\tTo print the stack trace, add the environment variable %s.}}",
         | 
| 23 35 | 
             
                      },
         | 
| 24 | 
            -
                      enable_automatic_reporting_prompt: {
         | 
| 25 | 
            -
                        question: "Automatically send error reports moving forward?",
         | 
| 26 | 
            -
                        yes: "Automatically send error reports to the Shopify team",
         | 
| 27 | 
            -
                        no: "Don't send error reports",
         | 
| 28 | 
            -
                        enabled: "Anonymized error reports will be sent to Shopify.",
         | 
| 29 | 
            -
                      },
         | 
| 30 36 | 
             
                      report_error: {
         | 
| 31 | 
            -
                        question: "Send an error report to Shopify?",
         | 
| 32 | 
            -
                        yes: " | 
| 33 | 
            -
                        no: " | 
| 37 | 
            +
                        question: "Send an anonymized error report to Shopify?",
         | 
| 38 | 
            +
                        yes: "Yes, send",
         | 
| 39 | 
            +
                        no: "No, don't send",
         | 
| 40 | 
            +
                      },
         | 
| 41 | 
            +
                    },
         | 
| 42 | 
            +
                    analytics: {
         | 
| 43 | 
            +
                      enable_prompt: {
         | 
| 44 | 
            +
                        uncaught_error: {
         | 
| 45 | 
            +
                          question: "Automatically send reports from now on?",
         | 
| 46 | 
            +
                          yes: "Yes, automatically send anonymized reports to Shopify",
         | 
| 47 | 
            +
                          no: "No, don't send",
         | 
| 48 | 
            +
                        },
         | 
| 49 | 
            +
                        usage: {
         | 
| 50 | 
            +
                          question: "Automatically send anonymized usage and error reports to Shopify? We use these"\
         | 
| 51 | 
            +
                            " to make development on Shopify better.",
         | 
| 52 | 
            +
                          yes: "Yes, automatically send anonymized reports to Shopify",
         | 
| 53 | 
            +
                          no: "No, don't send",
         | 
| 54 | 
            +
                        },
         | 
| 34 55 | 
             
                      },
         | 
| 35 56 | 
             
                    },
         | 
| 36 57 | 
             
                    connect: {
         | 
| @@ -168,15 +189,6 @@ module ShopifyCLI | |
| 168 189 | 
             
                      disabled_as_shopify_org: "Can't switch development stores logged in as {{green:Shopify partners org}}",
         | 
| 169 190 | 
             
                      success: "Switched development store to {{green:%s}}",
         | 
| 170 191 | 
             
                    },
         | 
| 171 | 
            -
             | 
| 172 | 
            -
                    monorail: {
         | 
| 173 | 
            -
                      consent_prompt: <<~MSG,
         | 
| 174 | 
            -
                        Would you like to enable anonymous usage reporting?
         | 
| 175 | 
            -
                        If you select “Yes”, we’ll collect data about which commands you use and which errors you encounter.
         | 
| 176 | 
            -
                        Sharing this anonymous data helps Shopify improve this tool.
         | 
| 177 | 
            -
                      MSG
         | 
| 178 | 
            -
                    },
         | 
| 179 | 
            -
             | 
| 180 192 | 
             
                    identity_auth: {
         | 
| 181 193 | 
             
                      error: {
         | 
| 182 194 | 
             
                        timeout: "Timed out while waiting for response from Shopify",
         | 
| @@ -493,7 +505,24 @@ module ShopifyCLI | |
| 493 505 |  | 
| 494 506 | 
             
                      MESSAGE
         | 
| 495 507 | 
             
                    },
         | 
| 496 | 
            -
             | 
| 508 | 
            +
                    reporting: {
         | 
| 509 | 
            +
                      help: <<~HELP,
         | 
| 510 | 
            +
                        Turns anonymous reporting on or off.
         | 
| 511 | 
            +
                          Usage: {{command:%s reporting on}}
         | 
| 512 | 
            +
                      HELP
         | 
| 513 | 
            +
                      invalid_argument: <<~MESSAGE,
         | 
| 514 | 
            +
                        {{command:%s reporting %s}} is not supported. The valid values are {{command:on}} or {{command:off}}
         | 
| 515 | 
            +
                      MESSAGE
         | 
| 516 | 
            +
                      missing_argument: <<~MESSAGE,
         | 
| 517 | 
            +
                        {{command:%s reporting}} expects an argument {{command:on}} or {{command:off}}
         | 
| 518 | 
            +
                      MESSAGE
         | 
| 519 | 
            +
                      turned_on_message: <<~MESSAGE,
         | 
| 520 | 
            +
                        Anonymized reports will be sent to Shopify.
         | 
| 521 | 
            +
                      MESSAGE
         | 
| 522 | 
            +
                      turned_off_message: <<~MESSAGE,
         | 
| 523 | 
            +
                        Turn on automatic reporting later wtih {{command:%s reporting on}}.
         | 
| 524 | 
            +
                      MESSAGE
         | 
| 525 | 
            +
                    },
         | 
| 497 526 | 
             
                    whoami: {
         | 
| 498 527 | 
             
                      help: <<~HELP,
         | 
| 499 528 | 
             
                        Identifies which partner organization or store you are currently logged into.
         | 
| @@ -0,0 +1,41 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module ShopifyCLI
         | 
| 4 | 
            +
              module Migrator
         | 
| 5 | 
            +
                module Migrations
         | 
| 6 | 
            +
                  # Before this migration, users configured automatic usage and error
         | 
| 7 | 
            +
                  # reporting independenty. We changed it to be a single configuration
         | 
| 8 | 
            +
                  # in the environment's configuration and therefore we need a migration
         | 
| 9 | 
            +
                  # to merge the configurations.
         | 
| 10 | 
            +
                  class MergeReportingConfiguration
         | 
| 11 | 
            +
                    def self.run
         | 
| 12 | 
            +
                      analytics_enabled = ShopifyCLI::Config.get_bool(
         | 
| 13 | 
            +
                        Constants::Config::Sections::Analytics::NAME,
         | 
| 14 | 
            +
                        Constants::Config::Sections::Analytics::Fields::ENABLED,
         | 
| 15 | 
            +
                        default: false
         | 
| 16 | 
            +
                      )
         | 
| 17 | 
            +
                      error_reporting_enabled = ShopifyCLI::Config.get_bool(
         | 
| 18 | 
            +
                        "error-tracking",
         | 
| 19 | 
            +
                        "automatic-reporting",
         | 
| 20 | 
            +
                        default: false
         | 
| 21 | 
            +
                      )
         | 
| 22 | 
            +
                      # Because we are merging configuration options, both need
         | 
| 23 | 
            +
                      # to be true to for the new flag to be true. Otherwise,
         | 
| 24 | 
            +
                      # we delete them and let the CLI prompt the user again.
         | 
| 25 | 
            +
                      should_merge_be_true = analytics_enabled && error_reporting_enabled
         | 
| 26 | 
            +
             | 
| 27 | 
            +
                      unless should_merge_be_true
         | 
| 28 | 
            +
                        ShopifyCLI::Config.unset(
         | 
| 29 | 
            +
                          Constants::Config::Sections::Analytics::NAME,
         | 
| 30 | 
            +
                          Constants::Config::Sections::Analytics::Fields::ENABLED
         | 
| 31 | 
            +
                        )
         | 
| 32 | 
            +
                        ShopifyCLI::Config.unset(
         | 
| 33 | 
            +
                          "error-tracking",
         | 
| 34 | 
            +
                          "automatic-reporting"
         | 
| 35 | 
            +
                        )
         | 
| 36 | 
            +
                      end
         | 
| 37 | 
            +
                    end
         | 
| 38 | 
            +
                  end
         | 
| 39 | 
            +
                end
         | 
| 40 | 
            +
              end
         | 
| 41 | 
            +
            end
         | 
    
        data/lib/shopify_cli/migrator.rb
    CHANGED
    
    | @@ -9,23 +9,21 @@ module ShopifyCLI | |
| 9 9 | 
             
                  migrations_directory: File.expand_path("migrator/migrations", __dir__)
         | 
| 10 10 | 
             
                )
         | 
| 11 11 | 
             
                  baseline_date = last_migration_date
         | 
| 12 | 
            -
                  unless baseline_date.nil? | 
| 13 | 
            -
                    migrations | 
| 14 | 
            -
                      .select  | 
| 15 | 
            -
                        m.date > baseline_date.to_i | 
| 16 | 
            -
                       | 
| 17 | 
            -
                      .each | 
| 12 | 
            +
                  unless baseline_date.nil?
         | 
| 13 | 
            +
                    migrations(migrations_directory: migrations_directory)
         | 
| 14 | 
            +
                      .select do |m|
         | 
| 15 | 
            +
                        m.date > baseline_date.to_i
         | 
| 16 | 
            +
                      end
         | 
| 17 | 
            +
                      .each(&:run)
         | 
| 18 18 | 
             
                  end
         | 
| 19 19 |  | 
| 20 20 | 
             
                  store_last_migration_date
         | 
| 21 21 | 
             
                end
         | 
| 22 22 |  | 
| 23 | 
            -
                private
         | 
| 24 | 
            -
             | 
| 25 23 | 
             
                def self.store_last_migration_date
         | 
| 26 24 | 
             
                  ShopifyCLI::DB.set(ShopifyCLI::Constants::StoreKeys::LAST_MIGRATION_DATE => Time.now.to_i)
         | 
| 27 25 | 
             
                end
         | 
| 28 | 
            -
             | 
| 26 | 
            +
             | 
| 29 27 | 
             
                def self.last_migration_date
         | 
| 30 28 | 
             
                  ShopifyCLI::DB.get(ShopifyCLI::Constants::StoreKeys::LAST_MIGRATION_DATE)
         | 
| 31 29 | 
             
                end
         | 
| @@ -35,7 +33,7 @@ module ShopifyCLI | |
| 35 33 | 
             
                    file_name = File.basename(file_path).gsub(".rb", "")
         | 
| 36 34 | 
             
                    file_name_components = file_name.split("_")
         | 
| 37 35 | 
             
                    date_timestamp = file_name_components[0].to_i
         | 
| 38 | 
            -
                    migration_name = file_name_components | 
| 36 | 
            +
                    migration_name = file_name_components.drop(1).join("_")
         | 
| 39 37 |  | 
| 40 38 | 
             
                    Migrator::Migration.new(
         | 
| 41 39 | 
             
                      name: migration_name,
         | 
| @@ -45,4 +43,4 @@ module ShopifyCLI | |
| 45 43 | 
             
                  end
         | 
| 46 44 | 
             
                end
         | 
| 47 45 | 
             
              end
         | 
| 48 | 
            -
            end
         | 
| 46 | 
            +
            end
         | 
| @@ -0,0 +1,64 @@ | |
| 1 | 
            +
            module ShopifyCLI
         | 
| 2 | 
            +
              module ReportingConfigurationController
         | 
| 3 | 
            +
                def self.enable_reporting(enabled)
         | 
| 4 | 
            +
                  ShopifyCLI::Config.set(
         | 
| 5 | 
            +
                    Constants::Config::Sections::Analytics::NAME,
         | 
| 6 | 
            +
                    Constants::Config::Sections::Analytics::Fields::ENABLED,
         | 
| 7 | 
            +
                    enabled
         | 
| 8 | 
            +
                  )
         | 
| 9 | 
            +
                end
         | 
| 10 | 
            +
             | 
| 11 | 
            +
                def self.reporting_prompted?
         | 
| 12 | 
            +
                  ShopifyCLI::Config.get_section(Constants::Config::Sections::Analytics::NAME).key?(
         | 
| 13 | 
            +
                    Constants::Config::Sections::Analytics::Fields::ENABLED
         | 
| 14 | 
            +
                  )
         | 
| 15 | 
            +
                end
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                def self.reporting_enabled?
         | 
| 18 | 
            +
                  ShopifyCLI::Config.get_bool(
         | 
| 19 | 
            +
                    Constants::Config::Sections::Analytics::NAME,
         | 
| 20 | 
            +
                    Constants::Config::Sections::Analytics::Fields::ENABLED,
         | 
| 21 | 
            +
                    default: false
         | 
| 22 | 
            +
                  )
         | 
| 23 | 
            +
                end
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                def self.check_or_prompt_report_automatically(source: :usage, prompt: true, context: ShopifyCLI::Context.new)
         | 
| 26 | 
            +
                  return false if ShopifyCLI::Environment.development? || ShopifyCLI::Environment.test?
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                  # If the terminal is not interactive we can't prompt the user.
         | 
| 29 | 
            +
                  return false unless ShopifyCLI::Environment.interactive?
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                  if reporting_prompted?
         | 
| 32 | 
            +
                    reporting_enabled?
         | 
| 33 | 
            +
                  elsif prompt
         | 
| 34 | 
            +
                    prompt_user(context: context, source: source)
         | 
| 35 | 
            +
                  else
         | 
| 36 | 
            +
                    false
         | 
| 37 | 
            +
                  end
         | 
| 38 | 
            +
                end
         | 
| 39 | 
            +
             | 
| 40 | 
            +
                def self.prompt_user(context:, source:)
         | 
| 41 | 
            +
                  enable_automatic_tracking = CLI::UI::Prompt.ask(
         | 
| 42 | 
            +
                    context.message("core.analytics.enable_prompt.#{source}.question")
         | 
| 43 | 
            +
                  ) do |handler|
         | 
| 44 | 
            +
                    handler.option(context.message("core.analytics.enable_prompt.#{source}.yes")) { |_| true }
         | 
| 45 | 
            +
                    handler.option(context.message("core.analytics.enable_prompt.#{source}.no")) { |_| false }
         | 
| 46 | 
            +
                  end
         | 
| 47 | 
            +
             | 
| 48 | 
            +
                  ShopifyCLI::Config.set(
         | 
| 49 | 
            +
                    Constants::Config::Sections::Analytics::NAME,
         | 
| 50 | 
            +
                    Constants::Config::Sections::Analytics::Fields::ENABLED,
         | 
| 51 | 
            +
                    enable_automatic_tracking
         | 
| 52 | 
            +
                  )
         | 
| 53 | 
            +
             | 
| 54 | 
            +
                  message = if enable_automatic_tracking
         | 
| 55 | 
            +
                    context.message("core.reporting.turned_on_message")
         | 
| 56 | 
            +
                  else
         | 
| 57 | 
            +
                    context.message("core.reporting.turned_off_message", ShopifyCLI::TOOL_NAME)
         | 
| 58 | 
            +
                  end
         | 
| 59 | 
            +
                  context.puts(message)
         | 
| 60 | 
            +
             | 
| 61 | 
            +
                  enable_automatic_tracking
         | 
| 62 | 
            +
                end
         | 
| 63 | 
            +
              end
         | 
| 64 | 
            +
            end
         | 
| @@ -0,0 +1,16 @@ | |
| 1 | 
            +
            module ShopifyCLI
         | 
| 2 | 
            +
              module Services
         | 
| 3 | 
            +
                class ReportingService < BaseService
         | 
| 4 | 
            +
                  attr_reader :enable
         | 
| 5 | 
            +
             | 
| 6 | 
            +
                  def initialize(enable:)
         | 
| 7 | 
            +
                    @enable = enable
         | 
| 8 | 
            +
                    super()
         | 
| 9 | 
            +
                  end
         | 
| 10 | 
            +
             | 
| 11 | 
            +
                  def call
         | 
| 12 | 
            +
                    ReportingConfigurationController.enable_reporting(enable)
         | 
| 13 | 
            +
                  end
         | 
| 14 | 
            +
                end
         | 
| 15 | 
            +
              end
         | 
| 16 | 
            +
            end
         | 
| @@ -9,12 +9,12 @@ module ShopifyCLI | |
| 9 9 | 
             
                  class Watcher
         | 
| 10 10 | 
             
                    include Observable
         | 
| 11 11 |  | 
| 12 | 
            -
                    def initialize(ctx, theme:, syncer:, ignore_filter: nil)
         | 
| 12 | 
            +
                    def initialize(ctx, theme:, syncer:, ignore_filter: nil, poll: false)
         | 
| 13 13 | 
             
                      @ctx = ctx
         | 
| 14 14 | 
             
                      @theme = theme
         | 
| 15 15 | 
             
                      @syncer = syncer
         | 
| 16 16 | 
             
                      @ignore_filter = ignore_filter
         | 
| 17 | 
            -
                      @listener = Listen.to(@theme.root) do |modified, added, removed|
         | 
| 17 | 
            +
                      @listener = Listen.to(@theme.root, force_polling: poll) do |modified, added, removed|
         | 
| 18 18 | 
             
                        changed
         | 
| 19 19 | 
             
                        notify_observers(modified, added, removed)
         | 
| 20 20 | 
             
                      end
         | 
| @@ -20,12 +20,12 @@ module ShopifyCLI | |
| 20 20 | 
             
                  class << self
         | 
| 21 21 | 
             
                    attr_accessor :ctx
         | 
| 22 22 |  | 
| 23 | 
            -
                    def start(ctx, root, port: 9292)
         | 
| 23 | 
            +
                    def start(ctx, root, bind: "127.0.0.1", port: 9292, poll: false)
         | 
| 24 24 | 
             
                      @ctx = ctx
         | 
| 25 25 | 
             
                      theme = DevelopmentTheme.new(ctx, root: root)
         | 
| 26 26 | 
             
                      ignore_filter = IgnoreFilter.from_path(root)
         | 
| 27 27 | 
             
                      @syncer = Syncer.new(ctx, theme: theme, ignore_filter: ignore_filter)
         | 
| 28 | 
            -
                      watcher = Watcher.new(ctx, theme: theme, syncer: @syncer, ignore_filter: ignore_filter)
         | 
| 28 | 
            +
                      watcher = Watcher.new(ctx, theme: theme, syncer: @syncer, ignore_filter: ignore_filter, poll: poll)
         | 
| 29 29 |  | 
| 30 30 | 
             
                      # Setup the middleware stack. Mimics Rack::Builder / config.ru, but in reverse order
         | 
| 31 31 | 
             
                      @app = Proxy.new(ctx, theme: theme, syncer: @syncer)
         | 
| @@ -74,6 +74,7 @@ module ShopifyCLI | |
| 74 74 | 
             
                      watcher.start
         | 
| 75 75 | 
             
                      WebServer.run(
         | 
| 76 76 | 
             
                        @app,
         | 
| 77 | 
            +
                        BindAddress: bind,
         | 
| 77 78 | 
             
                        Port: port,
         | 
| 78 79 | 
             
                        Logger: logger,
         | 
| 79 80 | 
             
                        AccessLog: [],
         | 
    
        data/lib/shopify_cli/version.rb
    CHANGED
    
    
    
        data/lib/shopify_cli.rb
    CHANGED
    
    | @@ -96,11 +96,13 @@ module ShopifyCLI | |
| 96 96 | 
             
                )
         | 
| 97 97 | 
             
              end
         | 
| 98 98 |  | 
| 99 | 
            +
              autoload :AppTypeDetector, "shopify_cli/app_type_detector"
         | 
| 99 100 | 
             
              autoload :Constants, "shopify_cli/constants"
         | 
| 100 101 | 
             
              autoload :Environment, "shopify_cli/environment"
         | 
| 101 102 | 
             
              autoload :AdminAPI, "shopify_cli/admin_api"
         | 
| 102 103 | 
             
              autoload :API, "shopify_cli/api"
         | 
| 103 104 | 
             
              autoload :Command, "shopify_cli/command"
         | 
| 105 | 
            +
              autoload :CommandOptions, "shopify_cli/command_options"
         | 
| 104 106 | 
             
              autoload :Commands, "shopify_cli/commands"
         | 
| 105 107 | 
             
              autoload :Connect, "shopify_cli/connect"
         | 
| 106 108 | 
             
              autoload :Context, "shopify_cli/context"
         | 
| @@ -123,9 +125,11 @@ module ShopifyCLI | |
| 123 125 | 
             
              autoload :Project, "shopify_cli/project"
         | 
| 124 126 | 
             
              autoload :ProjectCommands, "shopify_cli/project_commands"
         | 
| 125 127 | 
             
              autoload :ProjectType, "shopify_cli/project_type"
         | 
| 128 | 
            +
              autoload :ReportingConfigurationController, "shopify_cli/reporting_configuration_controller"
         | 
| 126 129 | 
             
              autoload :ResolveConstant, "shopify_cli/resolve_constant"
         | 
| 127 130 | 
             
              autoload :Resources, "shopify_cli/resources"
         | 
| 128 131 | 
             
              autoload :Result, "shopify_cli/result"
         | 
| 132 | 
            +
              autoload :Services, "shopify_cli/services"
         | 
| 129 133 | 
             
              autoload :Shopifolk, "shopify_cli/shopifolk"
         | 
| 130 134 | 
             
              autoload :SubCommand, "shopify_cli/sub_command"
         | 
| 131 135 | 
             
              autoload :Task, "shopify_cli/task"
         | 
    
        data/shopify-cli.gemspec
    CHANGED
    
    | @@ -33,11 +33,7 @@ Gem::Specification.new do |spec| | |
| 33 33 | 
             
              end
         | 
| 34 34 | 
             
              spec.bindir = "bin"
         | 
| 35 35 | 
             
              spec.require_paths = ["lib", "vendor"]
         | 
| 36 | 
            -
              spec. | 
| 37 | 
            -
              # Do NOT include `shopify` as a listed executable via `spec.executables`.
         | 
| 38 | 
            -
              # `ext/shopify-cli/extconf.rb` will dynamically create a script and soft-link
         | 
| 39 | 
            -
              # `/usr/local/bin/shopify` to that script, in order to "lock" the Ruby used to
         | 
| 40 | 
            -
              # a single Ruby (useful for debugging in multi-Ruby environments)
         | 
| 36 | 
            +
              spec.executables << "shopify"
         | 
| 41 37 |  | 
| 42 38 | 
             
              spec.add_development_dependency("bundler", "~> 2.2.2")
         | 
| 43 39 | 
             
              spec.add_development_dependency("rake", "~> 12.3", ">= 12.3.3")
         | 
| @@ -45,12 +41,5 @@ Gem::Specification.new do |spec| | |
| 45 41 |  | 
| 46 42 | 
             
              spec.add_dependency("bugsnag", "~> 6.22")
         | 
| 47 43 | 
             
              spec.add_dependency("listen", "~> 3.7.0")
         | 
| 48 | 
            -
             | 
| 49 | 
            -
              # Note: theme-check is _intentionally_ not specifying the third
         | 
| 50 | 
            -
              # digit. We _want_ new features to make their way into new installs
         | 
| 51 | 
            -
              # of the Shopify CLI. Otherwise updates need to be released twice.
         | 
| 52 | 
            -
              #
         | 
| 53 | 
            -
              # That is, DO USE ~> 1.X, DO NOT USE ~> 1.X.Y, this would unnecessarily
         | 
| 54 | 
            -
              # fix the feature version.
         | 
| 55 | 
            -
              spec.add_dependency("theme-check", "~> 1.7")
         | 
| 44 | 
            +
              spec.add_dependency("theme-check", "~> 1.7.2")
         | 
| 56 45 | 
             
            end
         | 
| @@ -0,0 +1,97 @@ | |
| 1 | 
            +
            require "open3"
         | 
| 2 | 
            +
            require "colorize"
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            module Utilities
         | 
| 5 | 
            +
              module Docker
         | 
| 6 | 
            +
                class Container
         | 
| 7 | 
            +
                  SHOPIFY_PATH = "/usr/src/app"
         | 
| 8 | 
            +
                  SHOPIFY_BIN_PATH = "/usr/src/app/bin/shopify"
         | 
| 9 | 
            +
             | 
| 10 | 
            +
                  Error = Class.new(StandardError)
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                  attr_reader :id, :env, :cwd, :xdg_config_home, :xdg_cache_home
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                  def initialize(id:, env:, cwd:)
         | 
| 15 | 
            +
                    @id = id
         | 
| 16 | 
            +
                    @cwd = cwd
         | 
| 17 | 
            +
                    @xdg_config_home = File.join(cwd, ".config")
         | 
| 18 | 
            +
                    @xdg_cache_home = File.join(cwd, ".cache")
         | 
| 19 | 
            +
                    @env = env.merge({
         | 
| 20 | 
            +
                      "XDG_CONFIG_HOME" => @xdg_config_home,
         | 
| 21 | 
            +
                      "XDG_CACHE_HOME" => @xdg_cache_home,
         | 
| 22 | 
            +
                    })
         | 
| 23 | 
            +
                  end
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                  def remove
         | 
| 26 | 
            +
                    _, stderr, stat = Open3.capture3(
         | 
| 27 | 
            +
                      "docker", "rm", "-f", @id
         | 
| 28 | 
            +
                    )
         | 
| 29 | 
            +
                    raise Error, stderr unless stat.success?
         | 
| 30 | 
            +
                  end
         | 
| 31 | 
            +
             | 
| 32 | 
            +
                  def capture_shopify(*args)
         | 
| 33 | 
            +
                    capture(*([SHOPIFY_BIN_PATH] + args))
         | 
| 34 | 
            +
                  end
         | 
| 35 | 
            +
             | 
| 36 | 
            +
                  def capture(*args, relative_dir: nil)
         | 
| 37 | 
            +
                    command = ["docker", "exec"]
         | 
| 38 | 
            +
                    cwd = if relative_dir.nil?
         | 
| 39 | 
            +
                      @cwd
         | 
| 40 | 
            +
                    else
         | 
| 41 | 
            +
                      File.join(@cwd, relative_dir)
         | 
| 42 | 
            +
                    end
         | 
| 43 | 
            +
                    command += ["-w", cwd]
         | 
| 44 | 
            +
                    @env.each do |env_name, env_value|
         | 
| 45 | 
            +
                      command += ["--env", "#{env_name}=#{env_value}"]
         | 
| 46 | 
            +
                    end
         | 
| 47 | 
            +
                    command << @id
         | 
| 48 | 
            +
                    command += args
         | 
| 49 | 
            +
             | 
| 50 | 
            +
                    out, err, stat = Open3.capture3(*command)
         | 
| 51 | 
            +
                    raise Error, err unless stat.success?
         | 
| 52 | 
            +
                    out
         | 
| 53 | 
            +
                  end
         | 
| 54 | 
            +
             | 
| 55 | 
            +
                  def exec_shopify(*args, relative_dir: nil)
         | 
| 56 | 
            +
                    exec(*([SHOPIFY_BIN_PATH] + args), relative_dir: relative_dir)
         | 
| 57 | 
            +
                  end
         | 
| 58 | 
            +
             | 
| 59 | 
            +
                  def exec(*args, relative_dir: nil)
         | 
| 60 | 
            +
                    if ARGV.include?("--verbose")
         | 
| 61 | 
            +
                      running_prefix = "Running command: #{args.join(" ")}"
         | 
| 62 | 
            +
                      STDOUT.puts(running_prefix.colorize(:yellow).bold)
         | 
| 63 | 
            +
                    end
         | 
| 64 | 
            +
                    command = ["docker", "exec"]
         | 
| 65 | 
            +
                    cwd = if relative_dir.nil?
         | 
| 66 | 
            +
                      @cwd
         | 
| 67 | 
            +
                    else
         | 
| 68 | 
            +
                      File.join(@cwd, relative_dir)
         | 
| 69 | 
            +
                    end
         | 
| 70 | 
            +
                    command += ["-w", cwd]
         | 
| 71 | 
            +
                    @env.each do |env_name, env_value|
         | 
| 72 | 
            +
                      command += ["--env", "#{env_name}=#{env_value}"]
         | 
| 73 | 
            +
                    end
         | 
| 74 | 
            +
                    command << @id
         | 
| 75 | 
            +
                    command += args
         | 
| 76 | 
            +
             | 
| 77 | 
            +
                    docker_prefix = "Docker (#{args.first}):"
         | 
| 78 | 
            +
             | 
| 79 | 
            +
                    if ARGV.include?("--verbose")
         | 
| 80 | 
            +
                      stat = Open3.popen3(*command) do |stdin, stdout, stderr, wait_thread|
         | 
| 81 | 
            +
                        Thread.new do
         | 
| 82 | 
            +
                          stdout.each { |l| STDOUT.puts("#{docker_prefix.colorize(:cyan).bold} #{l}") }
         | 
| 83 | 
            +
                          stderr.each { |l| STDERR.puts("#{docker_prefix.colorize(:red).bold} #{l}") }
         | 
| 84 | 
            +
                        end
         | 
| 85 | 
            +
                        stdin.close
         | 
| 86 | 
            +
             | 
| 87 | 
            +
                        wait_thread.value
         | 
| 88 | 
            +
                      end
         | 
| 89 | 
            +
                      raise StandardError, "The command #{args.first} failed" unless stat.success?
         | 
| 90 | 
            +
                    else
         | 
| 91 | 
            +
                      out, stat = Open3.capture2e(*command)
         | 
| 92 | 
            +
                      raise Error, out unless stat.success?
         | 
| 93 | 
            +
                    end
         | 
| 94 | 
            +
                  end
         | 
| 95 | 
            +
                end
         | 
| 96 | 
            +
              end
         | 
| 97 | 
            +
            end
         |