Repository: conda-forge/conda-smithy

Issue:
Remote-ci-setup handling cannot handle constraints anymore (since conda-smithy 3.26)
It seems that https://github.com/conda-forge/conda-smithy/commit/4a5ac16fc18281dd8e5922c13b333d31b50dd73f broke handling of `remote_ci_setup` setups that use constraints. For example, for compiler-rt, we need to use:
```yaml
remote_ci_setup:
  - conda-forge-ci-setup=3
  - py-lief<0.12
```

This will not rerender anymore with the newest conda-smithy (I tried various quoting and indentation patterns) -- from what I can tell this is due to
https://github.com/conda-forge/conda-smithy/blob/8ffa0d8f73e69dbcfe19c97c92b05e77187cad6a/conda_smithy/configure_feedstock.py#L2039-L2041
using `.name` unconditionally.

This has effectively made compiler-rt un-rerenderable (except with manual fixes), because we cannot remove the py-lief pin, since https://github.com/conda/conda-build/issues/4787 was only fixed in conda-build 3.26, which we still cannot pull into our CI due to https://github.com/conda-forge/boa-feedstock/issues/75. For a sample CI failure without the pin, see https://github.com/conda-forge/compiler-rt-feedstock/pull/83.

CC @jaimergp 

<details>
<summary>stacktrace</summary>

### Note the unbalanced quotes!

```
(builder) C:\Users\[...]\dev\conda-forge\compiler-rt-feedstock>conda smithy rerender
INFO:conda_smithy.configure_feedstock:Downloading conda-forge-pinning-2023.09.26.03.46.41
INFO:conda_smithy.configure_feedstock:Extracting conda-forge-pinning to C:\Users\[...]\AppData\Local\Temp\tmpjn62ot_j
Traceback (most recent call last):
  File "C:\Users\[...]\.conda\envs\builder\lib\site-packages\conda\models\version.py", line 43, in __call__
    return cls._cache_[arg]
KeyError: '<0.12"'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\Users\[...]\.conda\envs\builder\lib\site-packages\conda\models\version.py", line 43, in __call__
    return cls._cache_[arg]
KeyError: '0.12"'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\Users\[...]\.conda\envs\builder\Scripts\conda-smithy-script.py", line 9, in <module>
    sys.exit(main())
  File "C:\Users\[...]\.conda\envs\builder\lib\site-packages\conda_smithy\cli.py", line 669, in main
    args.subcommand_func(args)
  File "C:\Users\[...]\.conda\envs\builder\lib\site-packages\conda_smithy\cli.py", line 485, in __call__
    self._call(args, tmpdir)
  File "C:\Users\[...]\.conda\envs\builder\lib\site-packages\conda_smithy\cli.py", line 490, in _call
    configure_feedstock.main(
  File "C:\Users\[...]\.conda\envs\builder\lib\site-packages\conda_smithy\configure_feedstock.py", line 2357, in main
    config = _load_forge_config(forge_dir, exclusive_config_file, forge_yml)
  File "C:\Users\[...]\.conda\envs\builder\lib\site-packages\conda_smithy\configure_feedstock.py", line 2039, in _load_forge_config
    config["remote_ci_setup_names"] = [
  File "C:\Users\[...]\.conda\envs\builder\lib\site-packages\conda_smithy\configure_feedstock.py", line 2040, in <listcomp>
    MatchSpec(pkg).name for pkg in config["remote_ci_setup"]
  File "C:\Users\[...]\.conda\envs\builder\lib\site-packages\conda\models\match_spec.py", line 55, in __call__
    return super().__call__(**parsed)
  File "C:\Users\[...]\.conda\envs\builder\lib\site-packages\conda\models\match_spec.py", line 179, in __init__
    self._match_components = self._build_components(**kwargs)
  File "C:\Users\[...]\.conda\envs\builder\lib\site-packages\conda\models\match_spec.py", line 414, in _build_components
    return frozendict(_make_component(key, value) for key, value in kwargs.items())
  File "C:\Users\[...]\.conda\envs\builder\lib\site-packages\conda\_vendor\frozendict\__init__.py", line 21, in __init__
    self._dict = self.dict_cls(*args, **kwargs)
  File "C:\Users\[...]\.conda\envs\builder\lib\site-packages\conda\models\match_spec.py", line 414, in <genexpr>
    return frozendict(_make_component(key, value) for key, value in kwargs.items())
  File "C:\Users\[...]\.conda\envs\builder\lib\site-packages\conda\models\match_spec.py", line 428, in _make_component
    matcher = _implementors[field_name](value)
  File "C:\Users\[...]\.conda\envs\builder\lib\site-packages\conda\models\version.py", line 45, in __call__
    val = cls._cache_[arg] = super().__call__(arg)
  File "C:\Users\[...]\.conda\envs\builder\lib\site-packages\conda\models\version.py", line 516, in __init__
    vspec_str, matcher, is_exact = self.get_matcher(vspec)
  File "C:\Users\[...]\.conda\envs\builder\lib\site-packages\conda\models\version.py", line 570, in get_matcher
    self.matcher_vo = VersionOrder(vo_str)
  File "C:\Users\[...]\.conda\envs\builder\lib\site-packages\conda\models\version.py", line 45, in __call__
    val = cls._cache_[arg] = super().__call__(arg)
  File "C:\Users\[...]\.conda\envs\builder\lib\site-packages\conda\models\version.py", line 171, in __init__
    raise InvalidVersionSpec(vstr, "invalid character(s)")
conda.exceptions.InvalidVersionSpec: Invalid version '0.12"': invalid character(s)
```

</details>

Discussion:

Patch:
diff --git a/conda_smithy/configure_feedstock.py b/conda_smithy/configure_feedstock.py
index cc84a682..54b4e8ab 100644
--- a/conda_smithy/configure_feedstock.py
+++ b/conda_smithy/configure_feedstock.py
@@ -2037,7 +2037,8 @@ def _load_forge_config(forge_dir, exclusive_config_file, forge_yml=None):
         config["remote_ci_setup"]
     )
     config["remote_ci_setup_names"] = [
-        MatchSpec(pkg).name for pkg in config["remote_ci_setup"]
+        MatchSpec(pkg.strip('"').strip("'")).name
+        for pkg in config["remote_ci_setup"]
     ]
 
     # Older conda-smithy versions supported this with only one
diff --git a/news/1775-quotes b/news/1775-quotes
new file mode 100644
index 00000000..05f832a0
--- /dev/null
+++ b/news/1775-quotes
@@ -0,0 +1,23 @@
+**Added:**
+
+* <news item>
+
+**Changed:**
+
+* Fix ``MatchSpec`` parsing when ``remote_ci_setup`` specs are quoted. (#1773 via #1775)
+
+**Deprecated:**
+
+* <news item>
+
+**Removed:**
+
+* <news item>
+
+**Fixed:**
+
+* <news item>
+
+**Security:**
+
+* <news item>


Test patch:
diff --git a/tests/test_configure_feedstock.py b/tests/test_configure_feedstock.py
index 0f5ff5be..7c95718e 100644
--- a/tests/test_configure_feedstock.py
+++ b/tests/test_configure_feedstock.py
@@ -907,3 +907,22 @@ def test_conda_build_tools(config_yaml):
 
     with pytest.raises(AssertionError):
         assert load_forge_config()
+
+
+def test_remote_ci_setup(config_yaml):
+    load_forge_config = lambda: cnfgr_fdstk._load_forge_config(  # noqa
+        config_yaml,
+        exclusive_config_file=os.path.join(
+            config_yaml, "recipe", "default_config.yaml"
+        ),
+    )
+    cfg = load_forge_config()
+    with open(os.path.join(config_yaml, "conda-forge.yml"), "a+") as fp:
+        fp.write("remote_ci_setup: ['conda-forge-ci-setup=3', 'py-lief<0.12']")
+    cfg = load_forge_config()
+    # pylief was quoted due to <
+    assert cfg["remote_ci_setup"] == [
+        "conda-forge-ci-setup=3",
+        '"py-lief<0.12"',
+    ]
+    assert cfg["remote_ci_setup_names"] == ["conda-forge-ci-setup", "py-lief"]