Skip to content

Commit

Permalink
Feature: allow arbitrary defines in conan new templates (#8718)
Browse files Browse the repository at this point in the history
* - allow arbitray defines in templates

Signed-off-by: SSE4 <tomskside@gmail.com>

* - convert defines to dict earlier

Signed-off-by: SSE4 <tomskside@gmail.com>

* - add test

Signed-off-by: SSE4 <tomskside@gmail.com>
  • Loading branch information
SSE4 committed Mar 29, 2021
1 parent beaca41 commit 9106369
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 10 deletions.
20 changes: 13 additions & 7 deletions conans/client/cmd/new.py
Expand Up @@ -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:
Expand All @@ -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
Expand All @@ -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("/")
Expand Down Expand Up @@ -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)}
Expand Down Expand Up @@ -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
Expand All @@ -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)}
Expand Down
8 changes: 7 additions & 1 deletion conans/client/command.py
Expand Up @@ -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,
Expand All @@ -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):
"""
Expand Down
4 changes: 2 additions & 2 deletions conans/client/conan_api.py
Expand Up @@ -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,
Expand All @@ -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):
Expand Down
21 changes: 21 additions & 0 deletions conans/test/integration/command/new_test.py
Expand Up @@ -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"
Expand Down

0 comments on commit 9106369

Please sign in to comment.