From 9106369f726b9bf11891a94fd1fa2965a382b357 Mon Sep 17 00:00:00 2001 From: SSE4 Date: Mon, 29 Mar 2021 15:52:32 +0700 Subject: [PATCH] Feature: allow arbitrary defines in conan new templates (#8718) * - allow arbitray defines in templates Signed-off-by: SSE4 * - convert defines to dict earlier Signed-off-by: SSE4 * - add test Signed-off-by: SSE4 --- conans/client/cmd/new.py | 20 +++++++++++++------- conans/client/command.py | 8 +++++++- conans/client/conan_api.py | 4 ++-- conans/test/integration/command/new_test.py | 21 +++++++++++++++++++++ 4 files changed, 43 insertions(+), 10 deletions(-) diff --git a/conans/client/cmd/new.py b/conans/client/cmd/new.py index fd418150ff5..338a2a418f6 100644 --- a/conans/client/cmd/new.py +++ b/conans/client/cmd/new.py @@ -286,16 +286,17 @@ def test(self): """ -def _render_template(text, name, version, package_name): +def _render_template(text, name, version, package_name, defines): context = {'name': name, 'version': version, 'package_name': package_name, 'conan_version': client_version} + context.update(defines) t = Template(text, keep_trailing_newline=True) return t.render(**context) -def _get_files_from_template_dir(template_dir, name, version, package_name): +def _get_files_from_template_dir(template_dir, name, version, package_name, defines): files = [] for d, _, fs in os.walk(template_dir): for f in fs: @@ -306,9 +307,10 @@ def _get_files_from_template_dir(template_dir, name, version, package_name): out_files = dict() for f in files: f_path = os.path.join(template_dir, f) - rendered_path = _render_template(f, name=name, version=version, package_name=package_name) + rendered_path = _render_template(f, name=name, version=version, package_name=package_name, + defines=defines) rendered_file = _render_template(load(f_path), name=name, version=version, - package_name=package_name) + package_name=package_name, defines=defines) out_files[rendered_path] = rendered_file return out_files @@ -319,7 +321,7 @@ def cmd_new(ref, header=False, pure_c=False, test=False, exports_sources=False, osx_clang_versions=None, shared=None, upload_url=None, gitignore=None, gitlab_gcc_versions=None, gitlab_clang_versions=None, circleci_gcc_versions=None, circleci_clang_versions=None, circleci_osx_versions=None, - template=None, cache=None): + template=None, cache=None, defines=None): try: tokens = ref.split("@") name, version = tokens[0].split("/") @@ -347,6 +349,8 @@ def cmd_new(ref, header=False, pure_c=False, test=False, exports_sources=False, raise ConanException("'template' is incompatible with 'header', " "'sources', 'pure-c' and 'bare'") + defines = defines or dict() + if header: files = {"conanfile.py": conanfile_header.format(name=name, version=version, package_name=package_name)} @@ -384,7 +388,8 @@ def cmd_new(ref, header=False, pure_c=False, test=False, exports_sources=False, replaced = _render_template(load(template), name=name, version=version, - package_name=package_name) + package_name=package_name, + defines=defines) files = {"conanfile.py": replaced} elif template == "v2_cmake": from conans.assets.templates.new_v2_cmake import get_files @@ -398,7 +403,8 @@ def cmd_new(ref, header=False, pure_c=False, test=False, exports_sources=False, files = _get_files_from_template_dir(template_dir=template, name=name, version=version, - package_name=package_name) + package_name=package_name, + defines=defines) else: files = {"conanfile.py": conanfile.format(name=name, version=version, package_name=package_name)} diff --git a/conans/client/command.py b/conans/client/command.py index e5ddce6e764..1d1bc365a6f 100644 --- a/conans/client/command.py +++ b/conans/client/command.py @@ -199,8 +199,13 @@ def new(self, *args): help='Generate a .gitignore with the known patterns to excluded') parser.add_argument("-ciu", "--ci-upload-url", help='Define URL of the repository to upload') + parser.add_argument('-d', '--define', action='append') args = parser.parse_args(*args) + + defines = args.define or [] + defines = dict((n, v) for n, v in (d.split('=') for d in defines)) + self._warn_python_version() self._conan.new(args.name, header=args.header, pure_c=args.pure_c, test=args.test, exports_sources=args.sources, bare=args.bare, @@ -215,7 +220,8 @@ def new(self, *args): circleci_gcc_versions=args.ci_circleci_gcc, circleci_clang_versions=args.ci_circleci_clang, circleci_osx_versions=args.ci_circleci_osx, - template=args.template) + template=args.template, + defines=defines) def inspect(self, *args): """ diff --git a/conans/client/conan_api.py b/conans/client/conan_api.py index 8f462718b88..321c997e5a5 100644 --- a/conans/client/conan_api.py +++ b/conans/client/conan_api.py @@ -250,7 +250,7 @@ def new(self, name, header=False, pure_c=False, test=False, exports_sources=Fals osx_clang_versions=None, shared=None, upload_url=None, gitignore=None, gitlab_gcc_versions=None, gitlab_clang_versions=None, circleci_gcc_versions=None, circleci_clang_versions=None, circleci_osx_versions=None, - template=None): + template=None, defines=None): from conans.client.cmd.new import cmd_new cwd = os.path.abspath(cwd or os.getcwd()) files = cmd_new(name, header=header, pure_c=pure_c, test=test, @@ -265,7 +265,7 @@ def new(self, name, header=False, pure_c=False, test=False, exports_sources=Fals circleci_gcc_versions=circleci_gcc_versions, circleci_clang_versions=circleci_clang_versions, circleci_osx_versions=circleci_osx_versions, - template=template, cache=self.app.cache) + template=template, cache=self.app.cache, defines=defines) save_files(cwd, files) for f in sorted(files): diff --git a/conans/test/integration/command/new_test.py b/conans/test/integration/command/new_test.py index 0e3d6e53128..ef7c36ea7cf 100644 --- a/conans/test/integration/command/new_test.py +++ b/conans/test/integration/command/new_test.py @@ -29,6 +29,27 @@ class {{package_name}}Conan(ConanFile): self.assertIn('version = "0.1"', conanfile) self.assertIn('conan_version = "{}"'.format(client_version), conanfile) + def test_template_custom_definitions(self): + client = TestClient() + template1 = textwrap.dedent(""" + class {{package_name}}Conan(ConanFile): + name = "{{name}}" + version = "{{version}}" + conan_version = "{{conan_version}}" + license = "{{license}}" + homepage = "{{homepage}}" + """) + save(os.path.join(client.cache_folder, "templates/mytemplate.py"), template1) + client.run("new hello/0.1 --template=mytemplate.py " + "-d license=MIT -d homepage=http://example.com") + conanfile = client.load("conanfile.py") + self.assertIn("class HelloConan(ConanFile):", conanfile) + self.assertIn('name = "hello"', conanfile) + self.assertIn('version = "0.1"', conanfile) + self.assertIn('conan_version = "{}"'.format(client_version), conanfile) + self.assertIn('license = "MIT"', conanfile) + self.assertIn('homepage = "http://example.com"', conanfile) + def test_template_dir(self): client = TestClient() template_dir = "templates/command/new/t_dir"