Repository: Shopify/shopify-cli (Ruby)

Issue:
[Bug]: Ignore syntax changed?
### Please confirm that you have:

- [X] Searched [existing issues](https://github.com/Shopify/shopify-cli/issues) to see if your issue is a duplicate. (If you’ve found a duplicate issue, feel free to add additional information in a comment on it.)
- [X] Reproduced the issue in [the latest CLI version](https://github.com/Shopify/shopify-cli/releases).

### What type of project are you working on?

theme

### Expected behavior

I have a pull script that looks similar to the following:

```sh
#! /bin/bash
shopify theme pull src --ignore assets/theme.scss --ignore assets/css.css --ignore assets/component-*.css
```

previously, this worked.

new syntax needed:

```sh
shopify theme pull src --ignore assets/theme.scss assets/css.css assets/component-*.css
```

### Actual behavior

all the specified ignored files were in fact pulled except those in the **first ignore flag**

This broke from 2.11.0 -> 2.13.0 confirmed by downgrading shopify CLI.

### Stack trace

_No response_

### Reproduction steps

1. start with a fresh theme.
2. deploy the theme to remote `shopify theme push`
3. delete 2 random files
4. ignore both on a pull with `shopify --ignore file1 --ignore file2`
5. see that the second file is pulled while the first is not
6. delete both files again
7. ignore both on a pull with `shopify --ignore file1 file2`
8. see that both files are now ignored

### Operating System

Mac os monterey

### CLI version (run `shopify version` if you're not sure)

2.13.0

### Shell

zsh, bash

### Ruby version (run `ruby -v` if you're not sure)

ruby 2.6.8p205 (2021-07-07 revision 67951) [universal.x86_64-darwin21]

### What language and version are you using in your application?

NA


Discussion:
https://github.com/Shopify/shopify-cli/pull/2066
https://github.com/Shopify/shopify-cli/pull/2025
It would be preferable for us to support multiple ignore flags (either as opposed to or in addition to multiple args for a single flag if that is the new syntax)



Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 0b9bbaa81c..45ba6ca0d8 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,7 @@ From version 2.6.0, the sections in this file adhere to the [keep a changelog](h
 ### Fixed
 * [#2086](https://github.com/Shopify/shopify-cli/pull/2086): Improve check of dependency versions
 * [#2149](https://github.com/Shopify/shopify-cli/pull/2149): Fix `ThemeAdminAPI` not to handle asset errors
+* [#2122](https://github.com/Shopify/shopify-cli/pull/2122): Fix `--only`/`--ignore` flags parser to support multiple occurrences without quotes
 * [#2146](https://github.com/Shopify/shopify-cli/pull/2146): Prevent duplicate locales for Checkout extension localization
 
 ## Version 2.14.0
diff --git a/lib/project_types/theme/commands/pull.rb b/lib/project_types/theme/commands/pull.rb
index cd24721898..f4fa2be450 100644
--- a/lib/project_types/theme/commands/pull.rb
+++ b/lib/project_types/theme/commands/pull.rb
@@ -26,11 +26,11 @@ class Pull < ShopifyCLI::Command::SubCommand
         parser.on("-d", "--development") { flags[:development] = true }
         parser.on("-o", "--only=PATTERN", Conversions::IncludeGlob) do |pattern|
           flags[:includes] ||= []
-          flags[:includes] += pattern
+          flags[:includes] |= pattern
         end
         parser.on("-x", "--ignore=PATTERN", Conversions::IgnoreGlob) do |pattern|
           flags[:ignores] ||= []
-          flags[:ignores] += pattern
+          flags[:ignores] |= pattern
         end
       end
 
diff --git a/lib/project_types/theme/commands/push.rb b/lib/project_types/theme/commands/push.rb
index 7eb10be442..5f8205ba4e 100644
--- a/lib/project_types/theme/commands/push.rb
+++ b/lib/project_types/theme/commands/push.rb
@@ -30,11 +30,11 @@ class Push < ShopifyCLI::Command::SubCommand
         parser.on("-p", "--publish") { flags[:publish] = true }
         parser.on("-o", "--only=PATTERN", Conversions::IncludeGlob) do |pattern|
           flags[:includes] ||= []
-          flags[:includes] += pattern
+          flags[:includes] |= pattern
         end
         parser.on("-x", "--ignore=PATTERN", Conversions::IgnoreGlob) do |pattern|
           flags[:ignores] ||= []
-          flags[:ignores] += pattern
+          flags[:ignores] |= pattern
         end
       end
 
diff --git a/lib/project_types/theme/conversions/base_glob.rb b/lib/project_types/theme/conversions/base_glob.rb
index 77e0bcb7e4..6f2cf6886a 100644
--- a/lib/project_types/theme/conversions/base_glob.rb
+++ b/lib/project_types/theme/conversions/base_glob.rb
@@ -10,8 +10,22 @@ def register(parser)
 
         def convert(parser)
           argv = parser.default_argv
-          option_index = argv.index { |v| options.include?(v) }
+          values = []
+
+          option_indexes(argv).each do |option_index|
+            values += option_values(argv, parser, option_index)
+          end
+
+          values
+        end
+
+        def options
+          raise "`#{self.class.name}#options` must be defined"
+        end
+
+        private
 
+        def option_values(argv, parser, option_index)
           return [] if option_index.nil?
 
           start_index = option_index + 1
@@ -26,12 +40,13 @@ def convert(parser)
           values
         end
 
-        def options
-          raise "`#{self.class.name}#options` must be defined"
+        def option_indexes(argv)
+          argv
+            .each_with_index
+            .select { |item, _index| options.include?(item) }
+            .map(&:last)
         end
 
-        private
-
         def options_map(parser)
           map = {}
           parser.top.list.each do |option|


Test patch:
diff --git a/test/project_types/theme/conversions/base_glob_test.rb b/test/project_types/theme/conversions/base_glob_test.rb
index c2c576ce1c..ce2202613f 100644
--- a/test/project_types/theme/conversions/base_glob_test.rb
+++ b/test/project_types/theme/conversions/base_glob_test.rb
@@ -18,8 +18,9 @@ def test_convert_with_only
 
         actual_params = Conversions::BaseGlob.convert(parser)
         expected_params = [
-          "layout/password.liquid",
+          "layout/password1.liquid",
           "layout/theme.liquid",
+          "layout/password2.liquid",
         ]
 
         assert_equal(expected_params, actual_params)
@@ -54,11 +55,13 @@ def argv
           "push",
           "-d",
           "--only",
-          "layout/password.liquid",
+          "layout/password1.liquid",
           "layout/theme.liquid",
           "--ignore",
           "sections/announcement-bar.liquid",
           "sections/contact-form.liquid",
+          "--only",
+          "layout/password2.liquid",
         ]
       end