mirror of https://github.com/mamba-org/mamba.git
fix: Handle `MatchSpec` with brackets when parsing environments' history (#3490)
* fix: Adapt `parse_comment_line` to handle more `MatchSpec` Signed-off-by: Julien Jerphanion <git@jjerphan.xyz> * test: Add non-regression python test Signed-off-by: Julien Jerphanion <git@jjerphan.xyz> * test: Add non-regression C++ test Signed-off-by: Julien Jerphanion <git@jjerphan.xyz> * Apply review comments Signed-off-by: Julien Jerphanion <git@jjerphan.xyz> Co-authored-by: Johan Mabille <johan.mabille@gmail.com> * test: Skip test on Windows Signed-off-by: Julien Jerphanion <git@jjerphan.xyz> --------- Signed-off-by: Julien Jerphanion <git@jjerphan.xyz> Co-authored-by: Johan Mabille <johan.mabille@gmail.com>
This commit is contained in:
parent
d162759107
commit
b7367417f7
|
@ -126,12 +126,50 @@ namespace mamba
|
|||
{
|
||||
needle[0] = value[idx_start];
|
||||
idx_end = value.find_first_of(needle.c_str(), idx_search);
|
||||
|
||||
// Capturing `MatchSpecs` without internal quotes (e.g `libcurl`)
|
||||
if (idx_end != std::string::npos && value[idx_end - 1] != '\\')
|
||||
{
|
||||
pkg_specs.push_back(value.substr(idx_start + 1, idx_end - 1 - idx_start));
|
||||
idx_start = value.find_first_of("\'\"", idx_end + 1);
|
||||
idx_search = idx_start + 1;
|
||||
}
|
||||
// Capturing `MatchSpecs` with metadata (e.g `libcurl[version=\">=7.86,<8.10\"]`)
|
||||
else if (idx_end != std::string::npos && value[idx_end - 1] == '\\')
|
||||
{
|
||||
// Find if "[" is present in between idx_search and idx_end
|
||||
auto idx_bracket = value.find_first_of("[", idx_search);
|
||||
|
||||
// If "[" is present, then find the closing bracket
|
||||
if (idx_bracket != std::string::npos && idx_bracket < idx_end)
|
||||
{
|
||||
auto idx_closing_bracket = value.find_first_of("]", idx_bracket);
|
||||
if (idx_closing_bracket != std::string::npos)
|
||||
{
|
||||
auto start_string = idx_start + 1;
|
||||
auto end_string = idx_closing_bracket + 1;
|
||||
auto len_matchspec = end_string - start_string;
|
||||
|
||||
// Quotes are excluded (e.g. `libcurl[version=\">=7.86,<8.10\"]` is
|
||||
// extracted from `"libcurl[version=\">=7.86,<8.10\"]"`)
|
||||
auto match_spec = value.substr(start_string, len_matchspec);
|
||||
// Remove the backslash from the MatchSpec
|
||||
match_spec.erase(
|
||||
std::remove(match_spec.begin(), match_spec.end(), '\\'),
|
||||
match_spec.end()
|
||||
);
|
||||
pkg_specs.push_back(std::move(match_spec));
|
||||
idx_start = value.find_first_of("\'\"", end_string + 1);
|
||||
idx_search = idx_start + 1;
|
||||
}
|
||||
}
|
||||
// If "[" is not present, then there's a problem with the MatchSpec
|
||||
else if (idx_bracket == std::string::npos || idx_bracket > idx_end)
|
||||
{
|
||||
throw std::runtime_error("Parsing of history file failed at: " + value);
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
idx_search = idx_end;
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
==> 2024-10-02 12:29:11 <==
|
||||
# cmd: micromamba create -n repro2 pandas[version=">=0.25.2,<3"]
|
||||
# conda version: 3.8.0
|
||||
+conda-forge::_libgcc_mutex-0.1-conda_forge
|
||||
+conda-forge::python_abi-3.12-5_cp312
|
||||
+conda-forge::ca-certificates-2024.8.30-hbcca054_0
|
||||
+conda-forge::ld_impl_linux-64-2.43-h712a8e2_1
|
||||
+conda-forge::libgomp-14.1.0-h77fa898_1
|
||||
+conda-forge::_openmp_mutex-4.5-2_gnu
|
||||
+conda-forge::libgcc-14.1.0-h77fa898_1
|
||||
+conda-forge::libgfortran5-14.1.0-hc5f4f2c_1
|
||||
+conda-forge::libgcc-ng-14.1.0-h69a702a_1
|
||||
+conda-forge::openssl-3.3.2-hb9d3cd8_0
|
||||
+conda-forge::libexpat-2.6.3-h5888daf_0
|
||||
+conda-forge::libstdcxx-14.1.0-hc0a3c3a_1
|
||||
+conda-forge::libgfortran-14.1.0-h69a702a_1
|
||||
+conda-forge::libffi-3.4.2-h7f98852_5
|
||||
+conda-forge::libxcrypt-4.4.36-hd590300_1
|
||||
+conda-forge::bzip2-1.0.8-h4bc722e_7
|
||||
+conda-forge::ncurses-6.5-he02047a_1
|
||||
+conda-forge::libzlib-1.3.1-h4ab18f5_1
|
||||
+conda-forge::xz-5.2.6-h166bdaf_0
|
||||
+conda-forge::libuuid-2.38.1-h0b41bf4_0
|
||||
+conda-forge::libnsl-2.0.1-hd590300_0
|
||||
+conda-forge::libgfortran-ng-14.1.0-h69a702a_1
|
||||
+conda-forge::readline-8.2-h8228510_1
|
||||
+conda-forge::tk-8.6.13-noxft_h4845f30_101
|
||||
+conda-forge::libsqlite-3.46.1-hadc24fc_0
|
||||
+conda-forge::libopenblas-0.3.27-pthreads_hac2b453_1
|
||||
+conda-forge::libblas-3.9.0-24_linux64_openblas
|
||||
+conda-forge::libcblas-3.9.0-24_linux64_openblas
|
||||
+conda-forge::liblapack-3.9.0-24_linux64_openblas
|
||||
+conda-forge::tzdata-2024a-h8827d51_1
|
||||
+conda-forge::python-3.12.6-hc5c86c4_2_cpython
|
||||
+conda-forge::wheel-0.44.0-pyhd8ed1ab_0
|
||||
+conda-forge::setuptools-75.1.0-pyhd8ed1ab_0
|
||||
+conda-forge::pip-24.2-pyh8b19718_1
|
||||
+conda-forge::six-1.16.0-pyh6c4a22f_0
|
||||
+conda-forge::pytz-2024.1-pyhd8ed1ab_0
|
||||
+conda-forge::python-tzdata-2024.2-pyhd8ed1ab_0
|
||||
+conda-forge::python-dateutil-2.9.0-pyhd8ed1ab_0
|
||||
+conda-forge::numpy-2.1.1-py312h58c1407_0
|
||||
+conda-forge::pandas-2.2.3-py312hf9745cd_1
|
||||
# update specs: ["pandas[version=\">=0.25.2,<3\"]"]
|
|
@ -93,6 +93,18 @@ namespace mamba
|
|||
REQUIRE_EQ(updated_history_buffer.str(), check_buffer.str());
|
||||
}
|
||||
|
||||
TEST_CASE("parse_metadata")
|
||||
{
|
||||
auto channel_context = ChannelContext::make_conda_compatible(mambatests::context());
|
||||
|
||||
History history_instance(
|
||||
mambatests::test_data_dir / "history/parse_metadata",
|
||||
channel_context
|
||||
);
|
||||
// Must not throw
|
||||
std::vector<History::UserRequest> user_reqs = history_instance.get_user_requests();
|
||||
}
|
||||
|
||||
#ifndef _WIN32
|
||||
TEST_CASE("parse_segfault")
|
||||
{
|
||||
|
|
|
@ -1328,3 +1328,18 @@ def test_create_package_with_non_url_char(tmp_home, tmp_root_prefix):
|
|||
res = helpers.create("-n", "myenv", "-c", "conda-forge", "x264>=1!0", "--json")
|
||||
|
||||
assert any(pkg["name"] == "x264" for pkg in res["actions"]["LINK"])
|
||||
|
||||
|
||||
@pytest.mark.timeout(20)
|
||||
@pytest.mark.parametrize("shared_pkgs_dirs", [True], indirect=True)
|
||||
@pytest.mark.skipif(
|
||||
platform.system() == "Windows", reason="This test fails on Windows for unknown reasons"
|
||||
)
|
||||
def test_parsable_env_history_with_metadata(tmp_home, tmp_root_prefix, tmp_path):
|
||||
env_prefix = tmp_path / "env-micromamba-list"
|
||||
|
||||
res = helpers.create("-p", env_prefix, 'pandas[version=">=0.25.2,<3"]', "--json")
|
||||
assert res["success"]
|
||||
|
||||
# Must not hang
|
||||
helpers.umamba_list("-p", env_prefix, "--json")
|
||||
|
|
Loading…
Reference in New Issue