Skip to content

Commit 20d46e1

Browse files
committed
merged develop2
2 parents 529b700 + 86f29e1 commit 20d46e1

File tree

23 files changed

+377
-41
lines changed

23 files changed

+377
-41
lines changed

.ci/docker/conan-tests

+2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ ENV DEBIAN_FRONTEND=noninteractive
77
ENV PY36=3.6.15 \
88
PY38=3.8.6 \
99
PY39=3.9.2 \
10+
PY310=3.10.16 \
1011
PY312=3.12.3 \
1112
PY313=3.13.0 \
1213
CMAKE_3_15=/usr/share/cmake-3.15.7/bin/cmake \
@@ -95,6 +96,7 @@ RUN curl https://pyenv.run | bash && \
9596
pyenv install $PY36 && \
9697
pyenv install $PY38 && \
9798
pyenv install $PY39 && \
99+
pyenv install $PY310 && \
98100
pyenv install $PY312 && \
99101
pyenv install $PY313 && \
100102
pyenv global $PY39 && \

.github/workflows/linux-tests.yml

+22-7
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@ name: Linux tests
22

33
on:
44
workflow_call:
5+
inputs:
6+
python-versions:
7+
required: true
8+
type: string
59

610
jobs:
711
build_container:
@@ -49,7 +53,7 @@ jobs:
4953
options: --user conan
5054
strategy:
5155
matrix:
52-
python-version: [3.13, 3.9, 3.8, 3.6]
56+
python-version: ${{ fromJson(inputs.python-versions) }}
5357
test-type: [unittests, integration, functional]
5458
include:
5559
- test-type: unittests
@@ -92,19 +96,30 @@ jobs:
9296
linux_docker_tests:
9397
needs: build_container
9498
runs-on: ubuntu-latest
99+
container:
100+
image: ghcr.io/${{ github.repository_owner }}/conan-tests:${{ needs.build_container.outputs.image_tag }}
101+
options: --user conan
95102
strategy:
96103
matrix:
97-
python-version: [3.13, 3.9]
104+
# Use modern versions due to docker incompatibility with python <3.8
105+
python-version: ${{ github.event_name != 'pull_request' && fromJson('["3.13", "3.9"]') || fromJson('["3.10"]') }}
106+
98107
name: Docker Runner Tests (${{ matrix.python-version }})
99108
steps:
100-
- name: Set up Python ${{ matrix.python-version }}
101-
uses: actions/setup-python@v5
102-
with:
103-
python-version: ${{ matrix.python-version }}
104-
105109
- name: Checkout code
106110
uses: actions/checkout@v4
107111

112+
- name: Set up Python ${{ matrix.python-version }}
113+
run: |
114+
pyenv global ${{ matrix.python-version }}
115+
python --version
116+
117+
- name: Cache pip
118+
uses: actions/cache@v4
119+
with:
120+
path: ~/.cache/pip
121+
key: ${{ runner.os }}-pip-${{ matrix.python-version }}-${{ hashFiles('**/requirements_runner*.txt') }}
122+
108123
- name: Install dependencies
109124
run: |
110125
pip install --upgrade pip

.github/workflows/main.yml

+28
Original file line numberDiff line numberDiff line change
@@ -16,17 +16,44 @@ concurrency:
1616
cancel-in-progress: true
1717

1818
jobs:
19+
set_python_versions:
20+
runs-on: ubuntu-latest
21+
outputs:
22+
python_versions_linux_windows: ${{ steps.set_versions.outputs.python_versions_linux_windows }}
23+
python_versions_macos: ${{ steps.set_versions.outputs.python_versions_macos }}
24+
name: Determine Python versions
25+
steps:
26+
- name: Determine Python versions
27+
id: set_versions
28+
run: |
29+
if [[ "${{ github.ref }}" == "refs/heads/develop2" || "${{ github.ref }}" == refs/heads/release/* ]]; then
30+
echo "python_versions_linux_windows=['3.13', '3.6']" >> $GITHUB_OUTPUT
31+
echo "python_versions_macos=['3.13', '3.8']" >> $GITHUB_OUTPUT
32+
else
33+
echo "python_versions_linux_windows=['3.10']" >> $GITHUB_OUTPUT
34+
echo "python_versions_macos=['3.10']" >> $GITHUB_OUTPUT
35+
fi
36+
1937
linux_suite:
38+
needs: set_python_versions
2039
uses: ./.github/workflows/linux-tests.yml
2140
name: Linux test suite
41+
with:
42+
python-versions: ${{ needs.set_python_versions.outputs.python_versions_linux_windows }}
2243

2344
osx_suite:
45+
needs: set_python_versions
2446
uses: ./.github/workflows/osx-tests.yml
2547
name: OSX test suite
48+
with:
49+
python-versions: ${{ needs.set_python_versions.outputs.python_versions_macos }}
2650

2751
windows_suite:
52+
needs: set_python_versions
2853
uses: ./.github/workflows/win-tests.yml
2954
name: Windows test suite
55+
with:
56+
python-versions: ${{ needs.set_python_versions.outputs.python_versions_linux_windows }}
3057

3158
code_coverage:
3259
runs-on: ubuntu-latest
@@ -63,6 +90,7 @@ jobs:
6390
runs-on: ubuntu-latest
6491
name: Deploy to TestPyPI
6592
if: github.ref == 'refs/heads/develop2'
93+
needs: [linux_suite, osx_suite, windows_suite]
6694
steps:
6795
- name: Checkout code
6896
uses: actions/checkout@v4

.github/workflows/osx-tests.yml

+8-4
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@ name: OSX Tests
22

33
on:
44
workflow_call:
5+
inputs:
6+
python-versions:
7+
required: true
8+
type: string
59

610
jobs:
711
osx_setup:
@@ -11,10 +15,10 @@ jobs:
1115
- name: Checkout code
1216
uses: actions/checkout@v4
1317

14-
- name: Set up Python 3.8
18+
- name: Set up Python
1519
uses: actions/setup-python@v5
1620
with:
17-
python-version: 3.8
21+
python-version: '3.10'
1822

1923
- name: Cache pip packages
2024
id: cache-pip
@@ -32,7 +36,7 @@ jobs:
3236
pip install meson
3337
3438
- name: Uninstall default CMake
35-
run: brew uninstall cmake || true
39+
run: brew uninstall --formula cmake || true
3640

3741
- name: Cache Homebrew packages
3842
id: cache-brew
@@ -114,7 +118,7 @@ jobs:
114118
strategy:
115119
fail-fast: true
116120
matrix:
117-
python-version: [3.8, 3.12, 3.13]
121+
python-version: ${{ fromJson(inputs.python-versions) }}
118122
test-type: [unittests, integration, functional]
119123
include:
120124
- test-type: unittests

.github/workflows/win-tests.yml

+6-3
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,17 @@ name: Windows Tests
22

33
on:
44
workflow_call:
5+
inputs:
6+
python-versions:
7+
required: true
8+
type: string
59

610
jobs:
711
unit_integration_tests:
812
runs-on: windows-2022
913
strategy:
1014
matrix:
11-
python-version: [3.13, 3.8, 3.6]
15+
python-version: ${{ fromJson(inputs.python-versions) }}
1216
name: Unit & Integration Tests (${{ matrix.python-version }})
1317
steps:
1418
- name: Checkout code
@@ -59,8 +63,7 @@ jobs:
5963
runs-on: windows-2022
6064
strategy:
6165
matrix:
62-
python-version: [3.13, 3.8, 3.6]
63-
66+
python-version: ${{ fromJson(inputs.python-versions) }}
6467
name: Functional Tests (${{ matrix.python-version }})
6568
steps:
6669
- name: Checkout code

conan/__init__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@
22
from conan.internal.model.workspace import Workspace
33
from conan.internal.model.version import Version
44

5-
__version__ = '2.13.0-dev'
5+
__version__ = '2.14.0-dev'
66
conan_version = Version(__version__)

conan/api/conan_api.py

+3
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import os
12
import sys
23

34
from conan.api.output import init_colorama
@@ -35,6 +36,8 @@ def __init__(self, cache_folder=None):
3536
version = sys.version_info
3637
if version.major == 2 or version.minor < 6:
3738
raise ConanException("Conan needs Python >= 3.6")
39+
if cache_folder is not None and not os.path.isabs(cache_folder):
40+
raise ConanException("cache_folder has to be an absolute path")
3841

3942
init_colorama(sys.stderr)
4043
self.workspace = WorkspaceAPI(self)

conan/internal/conan_app.py

-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
from conans.client.loader import ConanFileLoader, load_python_file
99
from conans.client.remote_manager import RemoteManager
1010
from conans.client.rest.auth_manager import ConanApiAuthManager
11-
from conans.client.rest.conan_requester import ConanRequester
1211
from conan.internal.api.remotes.localdb import LocalDB
1312

1413

conan/internal/deploy.py

+12-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import filecmp
22
import os
33
import shutil
4+
import fnmatch
45

56
from conan.internal.cache.home_paths import HomePaths
67
from conan.api.output import ConanOutput
@@ -99,6 +100,8 @@ def full_deploy(graph, output_folder):
99100
def runtime_deploy(graph, output_folder):
100101
"""
101102
Deploy all the shared libraries and the executables of the dependencies in a flat directory.
103+
104+
It preserves symlinks in case the configuration tools.deployer:symlinks is True.
102105
"""
103106
conanfile = graph.root.conanfile
104107
output = ConanOutput(scope="runtime_deploy")
@@ -125,7 +128,7 @@ def runtime_deploy(graph, output_folder):
125128
if not os.path.isdir(libdir):
126129
output.warning(f"{dep.ref} {libdir} does not exist")
127130
continue
128-
count += _flatten_directory(dep, libdir, output_folder, symlinks, [".dylib", ".so"])
131+
count += _flatten_directory(dep, libdir, output_folder, symlinks, [".dylib*", ".so*"])
129132

130133
output.info(f"Copied {count} files from {dep.ref}")
131134
conanfile.output.success(f"Runtime deployed to folder: {output_folder}")
@@ -142,11 +145,15 @@ def _flatten_directory(dep, src_dir, output_dir, symlinks, extension_filter=None
142145
output = ConanOutput(scope="runtime_deploy")
143146
for src_dirpath, _, src_filenames in os.walk(src_dir, followlinks=symlinks):
144147
for src_filename in src_filenames:
145-
if extension_filter and not any(src_filename.endswith(ext) for ext in extension_filter):
148+
if extension_filter and not any(fnmatch.fnmatch(src_filename, f'*{ext}') for ext in extension_filter):
146149
continue
147150

148151
src_filepath = os.path.join(src_dirpath, src_filename)
149152
dest_filepath = os.path.join(output_dir, src_filename)
153+
154+
if not symlinks and os.path.islink(src_filepath):
155+
continue
156+
150157
if os.path.exists(dest_filepath):
151158
if filecmp.cmp(src_filepath, dest_filepath): # Be efficient, do not copy
152159
output.verbose(f"{dest_filepath} exists with same contents, skipping copy")
@@ -156,7 +163,9 @@ def _flatten_directory(dep, src_dir, output_dir, symlinks, extension_filter=None
156163

157164
try:
158165
file_count += 1
159-
shutil.copy2(src_filepath, dest_filepath, follow_symlinks=symlinks)
166+
# INFO: When follow_symlinks is false, and src is a symbolic link, it tries to
167+
# copy all metadata from the src symbolic link to the newly created dst link
168+
shutil.copy2(src_filepath, dest_filepath, follow_symlinks=not symlinks)
160169
output.verbose(f"Copied {src_filepath} into {output_dir}")
161170
except Exception as e:
162171
if "WinError 1314" in str(e):

conan/internal/model/conf.py

+1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
"core.download:retry_wait": "Seconds to wait between download attempts from Conan server",
2929
"core.download:download_cache": "Define path to a file download cache",
3030
"core.cache:storage_path": "Absolute path where the packages and database are stored",
31+
"core:update_policy": "(Legacy). If equal 'legacy' when multiple remotes, update based on order of remotes, only the timestamp of the first occurrence of each revision counts.",
3132
# Sources backup
3233
"core.sources:download_cache": "Folder to store the sources backup",
3334
"core.sources:download_urls": "List of URLs to download backup sources from",

conan/test/utils/tools.py

-10
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
import traceback
1212
import uuid
1313
import zipfile
14-
from collections import OrderedDict
1514
from contextlib import contextmanager
1615
from inspect import getframeinfo, stack
1716
from urllib.parse import urlsplit, urlunsplit
@@ -416,15 +415,6 @@ def __init__(self, cache_folder=None, current_folder=None, servers=None, inputs=
416415
self.cache_folder = cache_folder or os.path.join(temp_folder(path_with_spaces), ".conan2")
417416

418417
self.requester_class = requester_class
419-
420-
if servers and len(servers) > 1 and not isinstance(servers, OrderedDict):
421-
raise Exception(textwrap.dedent("""
422-
Testing framework error: Servers should be an OrderedDict. e.g:
423-
servers = OrderedDict()
424-
servers["r1"] = server
425-
servers["r2"] = TestServer()
426-
"""))
427-
428418
self.servers = servers or {}
429419
if servers is not False: # Do not mess with registry remotes
430420
self.update_servers()

conan/tools/cmake/cmakedeps/templates/config.py

+7
Original file line numberDiff line numberDiff line change
@@ -112,5 +112,12 @@ def template(self):
112112
REQUIRED_VARS {{ file_name }}_VERSION
113113
VERSION_VAR {{ file_name }}_VERSION)
114114
mark_as_advanced({{ file_name }}_FOUND {{ file_name }}_VERSION)
115+
116+
{% for prefix in additional_variables_prefixes %}
117+
set({{ prefix }}_FOUND 1)
118+
set({{ prefix }}_VERSION "{{ version }}")
119+
mark_as_advanced({{ prefix }}_FOUND {{ prefix }}_VERSION)
120+
{% endfor %}
121+
115122
{% endif %}
116123
""")

conan/tools/env/environment.py

+12-3
Original file line numberDiff line numberDiff line change
@@ -84,18 +84,19 @@ def __init__(self, name, value=None, separator=" ", path=False):
8484
def dumps(self):
8585
result = []
8686
path = "(path)" if self._path else ""
87+
sep = f"(sep={self._sep})" if self._sep != " " and not self._path else ""
8788
if not self._values: # Empty means unset
8889
result.append("{}=!".format(self._name))
8990
elif _EnvVarPlaceHolder in self._values:
9091
index = self._values.index(_EnvVarPlaceHolder)
9192
for v in reversed(self._values[:index]): # Reverse to prepend
92-
result.append("{}=+{}{}".format(self._name, path, v))
93+
result.append("{}=+{}{}{}".format(self._name, path, sep, v))
9394
for v in self._values[index+1:]:
94-
result.append("{}+={}{}".format(self._name, path, v))
95+
result.append("{}+={}{}{}".format(self._name, path, sep, v))
9596
else:
9697
append = ""
9798
for v in self._values:
98-
result.append("{}{}={}{}".format(self._name, append, path, v))
99+
result.append("{}{}={}{}{}".format(self._name, append, path, sep, v))
99100
append = "+"
100101
return "\n".join(result)
101102

@@ -644,6 +645,14 @@ def loads(text):
644645
env = Environment()
645646
if method == "unset":
646647
env.unset(name)
648+
elif value.strip().startswith("(sep="):
649+
value = value.strip()
650+
sep = value[5]
651+
value = value[7:]
652+
if value.strip().startswith("(path)"):
653+
msg = f"Cannot use (sep) and (path) qualifiers simultaneously: {line}"
654+
raise ConanException(msg)
655+
getattr(env, method)(name, value, separator=sep)
647656
else:
648657
if value.strip().startswith("(path)"):
649658
value = value.strip()

conan/tools/microsoft/visual.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ def generate(self, scope="build"):
117117
os_ = conanfile.settings.get_safe("os")
118118
build_os_ = conanfile.settings_build.get_safe("os")
119119

120-
if os_ != "Windows" or build_os_ != "Windows":
120+
if (os_ != "Windows" and os_ != "WindowsStore") or build_os_ != "Windows":
121121
return
122122

123123
compiler = conanfile.settings.get_safe("compiler")

0 commit comments

Comments
 (0)