Skip to content

Commit

Permalink
#457 First try for Cartesian product
Browse files Browse the repository at this point in the history
Signed-off-by: Uilian Ries <uilianries@gmail.com>
  • Loading branch information
uilianries committed Feb 28, 2020
1 parent 73fe6df commit 96fc642
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 11 deletions.
16 changes: 15 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,7 @@ There are also two additional parameters of the ``add_common_builds``:
Pass "False" to deactivate it or "lib_name:shared_option_name" to specify a custom option name, e.j: boost:my_shared``
- **dll_with_static_runtime**: Will add also the combination of runtime MT with shared libraries.
- **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).
- **build_all_options_values**: It includes all possible values for the listed options [#457](https://github.com/conan-io/conan-package-tools/issues/457).

```
from cpt.packager import ConanMultiPackager
Expand Down Expand Up @@ -366,7 +367,19 @@ In case you want to integrate CPT with other tools, for example you want to have

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

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

from cpt.packager import ConanMultiPackager


if __name__ == "__main__":
builder = ConanMultiPackager(reference="mypackage/0.1.0")
builder.add_common_builds(build_all_options_values=["mypackage:foo", "mypackage:bar"])
builder.run()

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**.
The method add_common_builds will generate a matrix including both *foo* and *bar* with all possible combinations.

## Using Docker

Expand Down Expand Up @@ -1141,14 +1154,15 @@ The current commit message can contain special messages:
## Complete ConanMultiPackager methods reference:
- **add_common_builds(shared_option_name=None, pure_c=True, dll_with_static_runtime=False, reference=None, header_only=True)**: Generate a set of package configurations and add them to the
- **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
list of packages that will be created.
- **shared_option_name**: If given, ConanMultiPackager will add different configurations for -o shared=True and -o shared=False.
- **pure_c**: ConanMultiPackager won't generate different builds for the **libstdc++** c++ standard library, because it is a pure C library.
- **dll_with_static_runtime**: generate also build for "MT" runtime when the library is shared.
- **reference**: Custom package reference
- **header_only**: Generate new builds following header-only options [#454](https://github.com/conan-io/conan-package-tools/issues/454)
- **build_all_options_values**: Include all values for the listed options [#457](https://github.com/conan-io/conan-package-tools/issues/457)
- **login(remote_name)**: Performs a `conan user` command in the specified remote.
Expand Down
30 changes: 21 additions & 9 deletions cpt/packager.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import sys
import copy
from collections import defaultdict
from itertools import product

import six
from conans import tools
Expand Down Expand Up @@ -494,6 +495,26 @@ def add_common_builds(self, shared_option_name=None, pure_c=True,

builds = self.build_generator.get_builds(pure_c, shared_option_name, dll_with_static_runtime, reference)

raw_options_for_building = [opt[opt.find(":")+1:] for opt in build_all_options_values]
for raw_option in reversed(raw_options_for_building):
if not isinstance(conanfile.options.get(raw_option), list):
raw_options_for_building.remove(raw_option)

if raw_options_for_building:
for settings, options, env_vars, build_requires, reference in reversed(builds):
cloned_options = copy.copy(conanfile.options)
for key, value in conanfile.options.items():
if key == "shared" or key == "header_only" or key in raw_options_for_building:
continue
else:
del cloned_options[key]
for key in cloned_options.keys():
if not key.startswith("{}:".format(reference.name)):
cloned_options["{}:{}".format(reference.name, key)] = cloned_options.pop(key)
combinations = [dict(zip(cloned_options, v)) for v in product(*cloned_options.values())]
for new_options in combinations:
builds.append(BuildConf(settings, new_options, env_vars, build_requires, reference))

if header_only_option and header_only:
if conanfile.default_options.get("header_only"):
cloned_builds = copy.deepcopy(builds)
Expand All @@ -507,15 +528,6 @@ def add_common_builds(self, shared_option_name=None, pure_c=True,
builds.append(BuildConf(copy.copy(settings), cloned_options, copy.copy(env_vars),
copy.copy(build_requires), reference))

for option in build_all_options_values:
cloned_builds = copy.deepcopy(builds)
for settings, options, env_vars, build_requires, reference in cloned_builds:
for key, value in conanfile.options.items():
if key == option[option.find(":")+1:] and isinstance(value, list):
for opt_value in value:
options.update({option, opt_value})
builds.extend(cloned_builds)

self._builds.extend(builds)

def add(self, settings=None, options=None, env_vars=None, build_requires=None, reference=None):
Expand Down
19 changes: 19 additions & 0 deletions cpt/test/integration/basic_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -322,3 +322,22 @@ def package_id(self):
if options.get("qux:header_only") == (not default_value):
header_only += 1
return header_only

def test_build_all_option_values(self):
conanfile = """from conans import ConanFile
class Pkg(ConanFile):
name = "qux"
version = "0.1.0"
options = {"shared": [True, False], "fPIC": [True, False],
"header_only": [True, False], "foo": [True, False],
"bar": ["baz", "qux", "foobar"], "blah": "ANY"}
default_options = {"shared": False, "fPIC": True, "header_only": False,
"foo": False, "bar": "baz", "blah": 42}
def configure(self):
self.output.info("hello all")
"""
tools.save(os.path.join(self.tmp_folder, "conanfile.py"), conanfile)
self.packager = ConanMultiPackager(out=self.output.write)
self.packager.add_common_builds(pure_c=False, build_all_options_values=["qux:foo", "qux:bar", "qux:blah"])
self.packager.run()
2 changes: 1 addition & 1 deletion cpt/test/unit/packager_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -1061,4 +1061,4 @@ def test_lockfile(self):
ci_manager=self.ci_manager)
builder.add_common_builds()
builder.run()
self.assertEquals("couse.lock", self.conan_api.calls[-1].kwargs["lockfile"])
self.assertEquals("couse.lock", self.conan_api.calls[-1].kwargs["lockfile"])

0 comments on commit 96fc642

Please sign in to comment.