Skip to content

Commit c010408

Browse files
authoredMar 10, 2020
Merge pull request #477 from conan-io/release/0.32.0
Release/0.32.0
2 parents a12d698 + d3f663e commit c010408

15 files changed

+923
-51
lines changed
 

‎README.md

+22-1
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,8 @@ There are also two additional parameters of the ``add_common_builds``:
272272
- **shared_option_name**: If your conanfile.py have an option **shared**, the generated builds will contain automatically the "True/False" combination for that option.
273273
Pass "False" to deactivate it or "lib_name:shared_option_name" to specify a custom option name, e.j: boost:my_shared``
274274
- **dll_with_static_runtime**: Will add also the combination of runtime MT with shared libraries.
275+
- **header_only**: If your conanfile.py have an option **header_only**, the generated builds will contain automatically the "True/False" combination for that option [#454](https://github.com/conan-io/conan-package-tools/issues/454).
276+
- **build_all_options_values**: It includes all possible values for the listed options [#457](https://github.com/conan-io/conan-package-tools/issues/457).
275277

276278
```
277279
from cpt.packager import ConanMultiPackager
@@ -365,7 +367,19 @@ In case you want to integrate CPT with other tools, for example you want to have
365367

366368
Alternatively you can use the `CPT_SUMMARY_FILE` environment variable to set the summary file path
367369

370+
## Using all values for custom options
371+
Sometimes you want to include more options to your matrix, including all possible combinations, so that, you can use **build_all_options_values**:
368372

373+
from cpt.packager import ConanMultiPackager
374+
375+
376+
if __name__ == "__main__":
377+
builder = ConanMultiPackager(reference="mypackage/0.1.0")
378+
builder.add_common_builds(build_all_options_values=["mypackage:foo", "mypackage:bar"])
379+
builder.run()
380+
381+
Now let's say mypackage's recipe contains the follow options: *shared*, *fPIC*, *foo* and *bar*. Both *foo* and *bar* can accept **True** or **False**.
382+
The method add_common_builds will generate a matrix including both *foo* and *bar* with all possible combinations.
369383

370384
## Using Docker
371385

@@ -1099,6 +1113,7 @@ Using **CONAN_CLANG_VERSIONS** env variable in Travis ci or Appveyor:
10991113
rebuild all packages.
11001114
- "all": Build all requirements.
11011115
- **test_folder**: Custom test folder consumed by Conan create, e.j .conan/test_package
1116+
- **lockfile**: Custom conan lockfile to be used, e.j. conan.lock. Default [None]
11021117
- **conanfile**: Custom conanfile consumed by Conan create. e.j. conanfile.py
11031118
- **config_url**: Conan config URL be installed before to build e.j https://github.com/bincrafters/conan-config.git
11041119
- **config_args**: Conan config arguments used when installing conan config
@@ -1139,12 +1154,15 @@ The current commit message can contain special messages:
11391154
11401155
## Complete ConanMultiPackager methods reference:
11411156
1142-
- **add_common_builds(shared_option_name=None, pure_c=True, dll_with_static_runtime=False)**: Generate a set of package configurations and add them to the
1157+
- **add_common_builds(shared_option_name=None, pure_c=True, dll_with_static_runtime=False, reference=None, header_only=True, build_all_options_values=None)**: Generate a set of package configurations and add them to the
11431158
list of packages that will be created.
11441159
11451160
- **shared_option_name**: If given, ConanMultiPackager will add different configurations for -o shared=True and -o shared=False.
11461161
- **pure_c**: ConanMultiPackager won't generate different builds for the **libstdc++** c++ standard library, because it is a pure C library.
11471162
- **dll_with_static_runtime**: generate also build for "MT" runtime when the library is shared.
1163+
- **reference**: Custom package reference
1164+
- **header_only**: Generate new builds following header-only options [#454](https://github.com/conan-io/conan-package-tools/issues/454)
1165+
- **build_all_options_values**: Include all values for the listed options [#457](https://github.com/conan-io/conan-package-tools/issues/457)
11481166
11491167
- **login(remote_name)**: Performs a `conan user` command in the specified remote.
11501168
@@ -1205,6 +1223,7 @@ This is especially useful for CI integration.
12051223
- **CONAN_ARCHS**: Architectures to build for, comma separated, e.g. "x86,x86_64"
12061224
- **CONAN_OPTIONS**: Conan build options, comma separated, e.g. "foobar:with_bar=True,foobar:with_qux=False"
12071225
- **CONAN_SHARED_OPTION_NAME**: Set `shared_option_name` by environment variable, e.g. "mypackagename:shared"
1226+
- **CONAN_BUILD_ALL_OPTIONS_VALUES**: Set `build_all_options_values` by environment variable, e.g. "mypackagename:foo,mypackagename:bar"
12081227
- **CONAN_BUILD_TYPES**: Build types to build for, comma separated, e.g. "Release,Debug"
12091228
- **CONAN_CPPSTDS**: List containing values for `compiler.cppstd`. Default None
12101229
- **CONAN_VISUAL_VERSIONS**: Visual versions, comma separated, e.g. "12,14"
@@ -1231,6 +1250,7 @@ This is especially useful for CI integration.
12311250
Set it with the bash executable path if it’s not in the PATH or you want to use a different one.
12321251
- **CONAN_PIP_USE_SUDO** Use "sudo" when invoking pip, by default it will use sudo when not using Windows and not running docker image "conanio/". "False" to deactivate.
12331252
- **CONAN_PIP_COMMAND** Run custom `pip` command when updating Conan. e.g. "/usr/bin/pip2"
1253+
- **CONAN_DOCKER_PIP_COMMAND** Run custom `pip` command when updating Conan and CPT in Docker container. e.g. "/usr/bin/pip2"
12341254
- **CONAN_DOCKER_USE_SUDO** Use "sudo" when invoking docker, by default it will use sudo when not using Windows. "False" to deactivate.
12351255
- **CONAN_ALLOW_GCC_MINORS** Declare this variable if you want to allow gcc >=5 versions with the minor (5.1, 6.3 etc).
12361256
- **CONAN_EXCLUDE_VCVARS_PRECOMMAND** For Visual Studio builds, it exclude the vcvars call to set the environment.
@@ -1246,6 +1266,7 @@ This is especially useful for CI integration.
12461266
- **CONAN_BASE_PROFILE**: Apply options, settings, etc. to this profile instead of `default`.
12471267
- **CONAN_IGNORE_SKIP_CI**: Ignore `[skip ci]` in commit message.
12481268
- **CONAN_CONANFILE**: Custom conanfile consumed by Conan create. e.j. conanfile.py
1269+
- **CONAN_LOCKFILE**: Custom conan lockfile to be used, e.j. conan.lock.
12491270
- **CPT_TEST_FOLDER**: Custom test_package path, e.j .conan/test_package
12501271
- **CONAN_FORCE_SELINUX**: Force docker to relabel file objects on the shared volumes
12511272
- **CONAN_SKIP_RECIPE_EXPORT**: If defined, the package recipe will only be exported on the first build.

‎appveyor.yml

+4-2
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,15 @@ environment:
33
- PYTHON: "C:\\Python27"
44
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
55
USE_UNSUPPORTED_CONAN_WITH_PYTHON_2: "1"
6-
- PYTHON: "C:\\Python35"
6+
TOXENV: "py27-conan-latest"
7+
8+
- PYTHON: "C:\\Python37"
79
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
810
USE_UNSUPPORTED_CONAN_WITH_PYTHON_2: "1"
11+
TOXENV: "py37-conan-latest"
912

1013
build: false
1114
install:
1215
- .ci/appveyor/install.bat
1316
test_script:
1417
- .ci/appveyor/test.bat
15-

‎cpt/__init__.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11

2-
__version__ = '0.31.2'
3-
NEWEST_CONAN_SUPPORTED = "1.22.300"
2+
__version__ = '0.32.0'
3+
NEWEST_CONAN_SUPPORTED = "1.23.000"
4+
45

56
def get_client_version():
67
from conans.model.version import Version

‎cpt/builds_generator.py

+89-24
Large diffs are not rendered by default.

‎cpt/ci_manager.py

+32
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,10 @@ def is_shippable():
3535
return os.getenv("SHIPPABLE", False)
3636

3737

38+
def is_github_actions():
39+
return os.getenv("GITHUB_ACTIONS", False)
40+
41+
3842
class CIManager(object):
3943
def __init__(self, printer):
4044

@@ -56,6 +60,8 @@ def __init__(self, printer):
5660
self.manager = AzurePipelinesManager(printer)
5761
elif is_shippable():
5862
self.manager = ShippableManager(printer)
63+
elif is_github_actions():
64+
self.manager = GitHubActionsManager(printer)
5965
else:
6066
self.manager = GenericManager(printer)
6167

@@ -281,6 +287,32 @@ def is_pull_request(self):
281287
return os.getenv("BUILD_REASON", "false") == "PullRequest"
282288

283289

290+
class GitHubActionsManager(GenericManager):
291+
def __init__(self, printer):
292+
super(GitHubActionsManager, self).__init__(printer)
293+
self.printer.print_message("CI detected: GitHub Actions")
294+
295+
def get_commit_msg(self):
296+
try:
297+
msg = subprocess.check_output("git log -1 --format=%s%n%b {}".format(self.get_commit_id()),
298+
shell=True).decode().strip()
299+
return msg
300+
except Exception:
301+
return None
302+
303+
def get_commit_id(self):
304+
return os.getenv("GITHUB_SHA", None)
305+
306+
def get_branch(self):
307+
branch = os.getenv("GITHUB_REF", None)
308+
if self.is_pull_request():
309+
branch = os.getenv("GITHUB_BASE_REF", "")
310+
return branch
311+
312+
def is_pull_request(self):
313+
return os.getenv("GITHUB_EVENT_NAME", "") == "pull_request"
314+
315+
284316
class ShippableManager(GenericManager):
285317

286318
def __init__(self, printer):

‎cpt/packager.py

+65-6
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22
import platform
33
import re
44
import sys
5+
import copy
56
from collections import defaultdict
7+
from itertools import product
68

79
import six
810
from conans import tools
@@ -139,7 +141,8 @@ def __init__(self, username=None, channel=None, runner=None,
139141
upload_dependencies=None,
140142
force_selinux=None,
141143
skip_recipe_export=False,
142-
update_dependencies=None):
144+
update_dependencies=None,
145+
lockfile=None):
143146

144147
conan_version = get_client_version()
145148

@@ -262,6 +265,7 @@ def __init__(self, username=None, channel=None, runner=None,
262265
pip_found = True if tools.os_info.is_windows else tools.which(self.pip_command)
263266
if not pip_found or not "pip" in self.pip_command:
264267
raise Exception("CONAN_PIP_COMMAND: '{}' is not a valid pip command.".format(self.pip_command))
268+
self.docker_pip_command = os.getenv("CONAN_DOCKER_PIP_COMMAND", "pip")
265269

266270
self.docker_shell = docker_shell or os.getenv("CONAN_DOCKER_SHELL")
267271

@@ -335,6 +339,8 @@ def __init__(self, username=None, channel=None, runner=None,
335339
get_bool_from_env("CONAN_SKIP_RECIPE_EXPORT")
336340
self.config_args = config_args or os.getenv("CONAN_CONFIG_ARGS")
337341

342+
self.lockfile = lockfile or os.getenv("CONAN_LOCKFILE")
343+
338344
def valid_pair(var, value):
339345
return (isinstance(value, six.string_types) or
340346
isinstance(value, bool) or
@@ -452,7 +458,8 @@ def login(self, remote_name):
452458
self.auth_manager.login(remote_name)
453459

454460
def add_common_builds(self, shared_option_name=None, pure_c=True,
455-
dll_with_static_runtime=False, reference=None):
461+
dll_with_static_runtime=False, reference=None, header_only=True,
462+
build_all_options_values=None):
456463
if reference:
457464
if "@" in reference:
458465
reference = ConanFileReference.loads(reference)
@@ -469,14 +476,63 @@ def add_common_builds(self, shared_option_name=None, pure_c=True,
469476
env_shared_option_name = os.getenv("CONAN_SHARED_OPTION_NAME", None)
470477
shared_option_name = env_shared_option_name if str(env_shared_option_name).lower() != "false" else False
471478

479+
build_all_options_values = build_all_options_values or split_colon_env("CONAN_BUILD_ALL_OPTIONS_VALUES") or []
480+
if not isinstance(build_all_options_values, list):
481+
raise Exception("'build_all_options_values' must be a list. e.g. ['foo:opt', 'foo:bar']")
482+
483+
conanfile = None
484+
if os.path.exists(os.path.join(self.cwd, self.conanfile)):
485+
conanfile = load_cf_class(os.path.join(self.cwd, self.conanfile), self.conan_api)
486+
487+
header_only_option = None
488+
if conanfile:
489+
if hasattr(conanfile, "options") and conanfile.options and "header_only" in conanfile.options:
490+
header_only_option = "%s:header_only" % reference.name
491+
472492
if shared_option_name is None:
473-
if os.path.exists(os.path.join(self.cwd, self.conanfile)):
474-
conanfile = load_cf_class(os.path.join(self.cwd, self.conanfile), self.conan_api)
493+
if conanfile:
475494
if hasattr(conanfile, "options") and conanfile.options and "shared" in conanfile.options:
476495
shared_option_name = "%s:shared" % reference.name
477496

478-
tmp = self.build_generator.get_builds(pure_c, shared_option_name, dll_with_static_runtime, reference)
479-
self._builds.extend(tmp)
497+
# filter only valid options
498+
raw_options_for_building = [opt[opt.find(":") + 1:] for opt in build_all_options_values]
499+
for raw_option in reversed(raw_options_for_building):
500+
if hasattr(conanfile, "options") and conanfile.options and \
501+
not isinstance(conanfile.options.get(raw_option), list):
502+
raw_options_for_building.remove(raw_option)
503+
if raw_options_for_building and conanfile:
504+
# get option and its values
505+
cloned_options = copy.copy(conanfile.options)
506+
for key, value in conanfile.options.items():
507+
if key == "shared" and shared_option_name:
508+
continue
509+
elif key not in raw_options_for_building:
510+
del cloned_options[key]
511+
for key in cloned_options.keys():
512+
# add package reference to the option name
513+
if not key.startswith("{}:".format(reference.name)):
514+
cloned_options["{}:{}".format(reference.name, key)] = cloned_options.pop(key)
515+
# combine all options x values (cartesian product)
516+
build_all_options_values = [dict(zip(cloned_options, v)) for v in product(*cloned_options.values())]
517+
518+
builds = self.build_generator.get_builds(pure_c, shared_option_name,
519+
dll_with_static_runtime, reference,
520+
build_all_options_values)
521+
522+
if header_only_option and header_only:
523+
if conanfile.default_options.get("header_only"):
524+
cloned_builds = copy.deepcopy(builds)
525+
for settings, options, env_vars, build_requires, reference in cloned_builds:
526+
options.update({header_only_option: False})
527+
builds.extend(cloned_builds)
528+
else:
529+
settings, options, env_vars, build_requires, reference = builds[0]
530+
cloned_options = copy.copy(options)
531+
cloned_options.update({header_only_option: True})
532+
builds.append(BuildConf(copy.copy(settings), cloned_options, copy.copy(env_vars),
533+
copy.copy(build_requires), reference))
534+
535+
self._builds.extend(builds)
480536

481537
def add(self, settings=None, options=None, env_vars=None, build_requires=None, reference=None):
482538
settings = settings or {}
@@ -628,6 +684,7 @@ def run_builds(self, curpage=None, total_pages=None, base_profile_name=None):
628684
config_args=self.config_args,
629685
upload_dependencies=self.upload_dependencies,
630686
conanfile=self.conanfile,
687+
lockfile=self.lockfile,
631688
skip_recipe_export=skip_recipe_export,
632689
update_dependencies=self.update_dependencies)
633690
r.run()
@@ -655,11 +712,13 @@ def run_builds(self, curpage=None, total_pages=None, base_profile_name=None):
655712
lcow_user_workaround=self.lcow_user_workaround,
656713
test_folder=self.test_folder,
657714
pip_install=self.pip_install,
715+
docker_pip_command=self.docker_pip_command,
658716
config_url=self.config_url,
659717
config_args=self.config_args,
660718
printer=self.printer,
661719
upload_dependencies=self.upload_dependencies,
662720
conanfile=self.conanfile,
721+
lockfile=self.lockfile,
663722
force_selinux=self.force_selinux,
664723
skip_recipe_export=skip_recipe_export,
665724
update_dependencies=self.update_dependencies)

‎cpt/requirements.txt

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
six>=1.10.0, <1.13.0
1+
six>=1.10.0, <1.15.0
22
conan>=1.7.0, <1.23.0
3-
tabulate==0.8.2
3+
tabulate>=0.8.0, <0.9.0

‎cpt/run_in_docker.py

+5-2
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,11 @@ def run():
3333
abs_profile_path = save_profile_to_tmp(profile_text)
3434
base_profile_text = unscape_env(os.getenv("CPT_BASE_PROFILE"))
3535
config_url = unscape_env(os.getenv("CPT_CONFIG_URL"))
36+
config_args = unscape_env(os.getenv("CPT_CONFIG_ARGS"))
3637
upload_dependencies = unscape_env(os.getenv("CPT_UPLOAD_DEPENDENCIES"))
3738
update_dependencies = unscape_env(os.getenv("CPT_UPDATE_DEPENDENCIES"))
3839
conanfile = unscape_env(os.getenv("CPT_CONANFILE"))
40+
lockfile = unscape_env(os.getenv("CPT_LOCKFILE"))
3941
skip_recipe_export = unscape_env(os.getenv("CPT_SKIP_RECIPE_EXPORT"))
4042
if base_profile_text:
4143
base_profile_name = unscape_env(os.getenv("CPT_BASE_PROFILE_NAME"))
@@ -46,10 +48,11 @@ def run():
4648
runner = CreateRunner(abs_profile_path, reference, conan_api, uploader,
4749
build_policy=build_policy, printer=printer, upload=upload,
4850
upload_only_recipe=upload_only_recipe,
49-
test_folder=test_folder, config_url=config_url,
51+
test_folder=test_folder, config_url=config_url, config_args=config_args,
5052
upload_dependencies=upload_dependencies, conanfile=conanfile,
5153
skip_recipe_export=skip_recipe_export,
52-
update_dependencies=update_dependencies)
54+
update_dependencies=update_dependencies,
55+
lockfile=lockfile)
5356
runner.run()
5457

5558

‎cpt/runner.py

+19-7
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ def __init__(self, profile_abs_path, reference, conan_api, uploader,
2020
cwd=None, printer=None, upload=False, upload_only_recipe=None,
2121
test_folder=None, config_url=None, config_args=None,
2222
upload_dependencies=None, conanfile=None, skip_recipe_export=False,
23-
update_dependencies=False):
23+
update_dependencies=False, lockfile=None):
2424

2525
self.printer = printer or Printer()
2626
self._cwd = cwd or os.getcwd()
@@ -37,6 +37,7 @@ def __init__(self, profile_abs_path, reference, conan_api, uploader,
3737
self._config_args = config_args
3838
self._upload_only_recipe = upload_only_recipe
3939
self._conanfile = conanfile
40+
self._lockfile = lockfile
4041
self._upload_dependencies = upload_dependencies.split(",") if \
4142
isinstance(upload_dependencies, str) else \
4243
upload_dependencies
@@ -124,7 +125,8 @@ def run(self):
124125
profile_names=[self._profile_abs_path],
125126
test_folder=self._test_folder,
126127
not_export=self.skip_recipe_export,
127-
update=self._update_dependencies)
128+
update=self._update_dependencies,
129+
lockfile=self._lockfile)
128130
except exc_class as e:
129131
self.printer.print_rule()
130132
self.printer.print_message("Skipped configuration by the recipe: "
@@ -168,14 +170,16 @@ def __init__(self, profile_text, base_profile_text, base_profile_name, reference
168170
lcow_user_workaround="",
169171
test_folder=None,
170172
pip_install=None,
173+
docker_pip_command=None,
171174
config_url=None,
172175
config_args=None,
173176
printer=None,
174177
upload_dependencies=None,
175178
conanfile=None,
176179
force_selinux=None,
177180
skip_recipe_export=False,
178-
update_dependencies=False):
181+
update_dependencies=False,
182+
lockfile=None):
179183

180184
self.printer = printer or Printer()
181185
self._upload = upload
@@ -201,10 +205,12 @@ def __init__(self, profile_text, base_profile_text, base_profile_name, reference
201205
self._runner = PrintRunner(runner, self.printer)
202206
self._test_folder = test_folder
203207
self._pip_install = pip_install
208+
self._docker_pip_command = docker_pip_command
204209
self._config_url = config_url
205210
self._config_args = config_args
206211
self._upload_dependencies = upload_dependencies or []
207212
self._conanfile = conanfile
213+
self._lockfile = lockfile
208214
self._force_selinux = force_selinux
209215
self._skip_recipe_export = skip_recipe_export
210216
self._update_dependencies = update_dependencies
@@ -213,18 +219,23 @@ def _pip_update_conan_command(self):
213219
commands = []
214220
# Hack for testing when retrieving cpt from artifactory repo
215221
if "conan-package-tools" not in self._conan_pip_package:
216-
commands.append("%s pip install conan_package_tools==%s "
222+
commands.append("%s %s install conan_package_tools==%s "
217223
"--upgrade --no-cache" % (self._sudo_pip_command,
224+
self._docker_pip_command,
218225
package_tools_version))
219226

220227
if self._conan_pip_package:
221-
commands.append("%s pip install %s --no-cache" % (self._sudo_pip_command,
228+
commands.append("%s %s install %s --no-cache" % (self._sudo_pip_command,
229+
self._docker_pip_command,
222230
self._conan_pip_package))
223231
else:
224-
commands.append("%s pip install conan --upgrade --no-cache" % self._sudo_pip_command)
232+
commands.append("%s %s install conan --upgrade --no-cache" % (self._sudo_pip_command,
233+
self._docker_pip_command))
225234

226235
if self._pip_install:
227-
commands.append("%s pip install %s --upgrade --no-cache" % (self._sudo_pip_command, " ".join(self._pip_install)))
236+
commands.append("%s %s install %s --upgrade --no-cache" % (self._sudo_pip_command,
237+
self._docker_pip_command,
238+
" ".join(self._pip_install)))
228239

229240
command = " && ".join(commands)
230241
return command
@@ -330,6 +341,7 @@ def get_env_vars(self):
330341
ret["CPT_CONFIG_ARGS"] = escape_env(self._config_args)
331342
ret["CPT_UPLOAD_DEPENDENCIES"] = escape_env(self._upload_dependencies)
332343
ret["CPT_CONANFILE"] = escape_env(self._conanfile)
344+
ret["CPT_LOCKFILE"] = escape_env(self._lockfile)
333345
ret["CPT_SKIP_RECIPE_EXPORT"] = self._skip_recipe_export
334346
ret["CPT_UPDATE_DEPENDENCIES"] = self._update_dependencies
335347

‎cpt/test/integration/basic_test.py

+58
Original file line numberDiff line numberDiff line change
@@ -283,3 +283,61 @@ def set_version(self):
283283
self.packager = ConanMultiPackager(out=self.output.write)
284284
self.packager.add_common_builds(pure_c=False)
285285
self.packager.run()
286+
287+
def test_header_only_option_true(self):
288+
header_only = self._test_header_only(False)
289+
self.assertEqual(header_only, 1)
290+
self.packager.run()
291+
292+
def test_header_only_option_false(self):
293+
header_only = self._test_header_only(True)
294+
self.assertEqual(header_only, int(len(self.packager.builds) / 2))
295+
self.packager.run()
296+
297+
def _test_header_only(self, default_value):
298+
conanfile = """from conans import ConanFile
299+
class Pkg(ConanFile):
300+
name = "qux"
301+
version = "0.1.0"
302+
settings = "os"
303+
options = {"header_only": [True, False], "shared": [True, False], "fPIC": [True, False]}
304+
default_options = {"header_only": %s, "shared": False, "fPIC": True}
305+
306+
def configure(self):
307+
if self.options.header_only:
308+
del self.options.shared
309+
del self.options.fPIC
310+
311+
def package_id(self):
312+
if self.options.header_only:
313+
self.info.header_only()
314+
""" % default_value
315+
tools.save(os.path.join(self.tmp_folder, "conanfile.py"), conanfile)
316+
self.packager = ConanMultiPackager(out=self.output.write)
317+
self.packager.add_common_builds(pure_c=False)
318+
319+
header_only = 0
320+
for build in self.packager.builds:
321+
_, options, _, _ = build
322+
if options.get("qux:header_only") == (not default_value):
323+
header_only += 1
324+
return header_only
325+
326+
def test_build_all_option_values(self):
327+
conanfile = """from conans import ConanFile
328+
class Pkg(ConanFile):
329+
name = "qux"
330+
version = "0.1.0"
331+
options = {"shared": [True, False], "fPIC": [True, False],
332+
"header_only": [True, False], "foo": [True, False],
333+
"bar": ["baz", "qux", "foobar"], "blah": "ANY"}
334+
default_options = {"shared": False, "fPIC": True, "header_only": False,
335+
"foo": False, "bar": "baz", "blah": 42}
336+
337+
def configure(self):
338+
self.output.info("hello all")
339+
"""
340+
tools.save(os.path.join(self.tmp_folder, "conanfile.py"), conanfile)
341+
self.packager = ConanMultiPackager(out=self.output.write)
342+
self.packager.add_common_builds(pure_c=False, build_all_options_values=["qux:foo", "qux:bar", "qux:blah"])
343+
self.packager.run()

‎cpt/test/integration/docker_test.py

+34
Original file line numberDiff line numberDiff line change
@@ -200,3 +200,37 @@ def test_docker_run_android(self):
200200
self.assertIn("compiler=clang", output)
201201
self.assertIn("arch=x86_64", output)
202202
self.assertIn("Cross-build from 'Linux:x86_64' to 'Android:x86_64'", output)
203+
204+
@unittest.skipUnless(is_linux_and_have_docker(), "Requires Linux and Docker")
205+
def test_docker_custom_pip_command(self):
206+
conanfile = """from conans import ConanFile
207+
import os
208+
209+
class Pkg(ConanFile):
210+
settings = "os", "compiler", "build_type", "arch"
211+
requires = "zlib/1.2.11@conan/stable"
212+
213+
def build(self):
214+
pass
215+
"""
216+
self.save_conanfile(conanfile)
217+
with tools.environment_append({"CONAN_DOCKER_ENTRY_SCRIPT": "pip install -U /tmp/cpt",
218+
"CONAN_USERNAME": "bar",
219+
"CONAN_DOCKER_IMAGE": "conanio/gcc8",
220+
"CONAN_REFERENCE": "foo/0.0.1@bar/testing",
221+
"CONAN_DOCKER_RUN_OPTIONS": "--network=host, --add-host=google.com:8.8.8.8 -v{}:/tmp/cpt".format(
222+
self.root_project_folder),
223+
"CONAN_DOCKER_IMAGE_SKIP_UPDATE": "TRUE",
224+
"CONAN_FORCE_SELINUX": "TRUE",
225+
"CONAN_DOCKER_SHELL": "/bin/bash -c",
226+
"CONAN_DOCKER_PIP_COMMAND": "foobar"
227+
}):
228+
self.packager = ConanMultiPackager(gcc_versions=["8"],
229+
archs=["x86_64"],
230+
build_types=["Release"],
231+
out=self.output.write)
232+
self.packager.add({})
233+
with self.assertRaises(Exception) as raised:
234+
self.packager.run()
235+
self.assertIn("Error updating the image", str(raised.exception))
236+
self.assertIn("foobar install conan_package_tools", str(raised.exception))

‎cpt/test/unit/ci_manager_test.py

+22
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,28 @@ def test_shippable_instance(self):
195195
self.assertEquals(manager.is_pull_request(), True)
196196
self.assertEquals(manager.is_tag(), True)
197197

198+
def test_github_actions_instance(self):
199+
gha_env = {"GITHUB_ACTIONS": "true",
200+
"GITHUB_SHA": "98e984eacf4e3dfea431c8850c8c181a08e8cf3d",
201+
"GITHUB_REF": "testing/5.6.5",
202+
"GITHUB_BASE_REF": "testing/5.6.5",
203+
"GITHUB_EVENT_NAME": "push"}
204+
with tools.environment_append(gha_env):
205+
manager = CIManager(self.printer)
206+
self.assertEquals(manager.get_branch(), gha_env["GITHUB_REF"])
207+
self.assertEquals(manager.get_commit_id(), gha_env["GITHUB_SHA"])
208+
self.assertEquals(manager.is_pull_request(), False)
209+
210+
gha_env = {"GITHUB_ACTIONS": "true",
211+
"GITHUB_SHA": "98e984eacf4e3dfea431c8850c8c181a08e8cf3d",
212+
"GITHUB_REF": "quick_fix",
213+
"GITHUB_BASE_REF": "testing/5.6.5",
214+
"GITHUB_EVENT_NAME": "pull_request"}
215+
with tools.environment_append(gha_env):
216+
manager = CIManager(self.printer)
217+
self.assertEquals(manager.get_branch(), gha_env["GITHUB_BASE_REF"])
218+
self.assertEquals(manager.get_commit_id(), gha_env["GITHUB_SHA"])
219+
self.assertEquals(manager.is_pull_request(), True)
198220

199221
def test_build_policy(self):
200222
# Travis

‎cpt/test/unit/generators_test.py

+536-2
Large diffs are not rendered by default.

‎cpt/test/unit/packager_test.py

+32-1
Original file line numberDiff line numberDiff line change
@@ -557,7 +557,7 @@ def test_multiple_references(self):
557557
for _, _, _, _, reference in builder.items:
558558
self.assertTrue(str(reference) in ("lib/1.0@lasote/mychannel", "lib/2.0@lasote/mychannel"))
559559

560-
def select_defaults_test(self):
560+
def test_select_defaults_test(self):
561561
with tools.environment_append({"CONAN_REFERENCE": "zlib/1.2.8"}):
562562
builder = ConanMultiPackager(platform_info=platform_mock_for("Linux"),
563563
gcc_versions=["4.8", "5"],
@@ -1031,3 +1031,34 @@ def _check_run_calls(skip_recipe_export):
10311031
packager.add_common_builds()
10321032
packager.run()
10331033
_check_run_calls(True)
1034+
1035+
def test_lockfile(self):
1036+
builder = ConanMultiPackager(username="pepe", channel="testing",
1037+
reference="Hello/0.1", password="password",
1038+
visual_versions=[], gcc_versions=[],
1039+
apple_clang_versions=[],
1040+
runner=self.runner,
1041+
conan_api=self.conan_api,
1042+
remotes="otherurl",
1043+
platform_info=platform_mock_for("Darwin"),
1044+
lockfile="foobar.lock",
1045+
ci_manager=self.ci_manager)
1046+
builder.add_common_builds()
1047+
builder.run()
1048+
self.assertEquals("foobar.lock", self.conan_api.calls[-1].kwargs["lockfile"])
1049+
1050+
with tools.environment_append({"CONAN_LOCKFILE": "couse.lock"}):
1051+
self.conan_api = MockConanAPI()
1052+
builder = ConanMultiPackager(username="pepe", channel="testing",
1053+
reference="Hello/0.1", password="password",
1054+
visual_versions=[], gcc_versions=[],
1055+
apple_clang_versions=[],
1056+
runner=self.runner,
1057+
conan_api=self.conan_api,
1058+
remotes="otherurl",
1059+
platform_info=platform_mock_for("Darwin"),
1060+
build_policy=None,
1061+
ci_manager=self.ci_manager)
1062+
builder.add_common_builds()
1063+
builder.run()
1064+
self.assertEquals("couse.lock", self.conan_api.calls[-1].kwargs["lockfile"])

‎cpt/tools.py

-2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
import os
2-
import subprocess
32

43

54
def get_bool_from_env(var_name):
6-
import os
75
val = os.getenv(var_name, None)
86
return str(val).lower() not in ("0", "none", "false")
97

0 commit comments

Comments
 (0)
Please sign in to comment.