Skip to content

Commit

Permalink
Add support to ev-cli for custom license headers (#168)
Browse files Browse the repository at this point in the history
* Add support to ev-cli for custom license headers
* Add support for license dir in current workdir (eg. everest-core/licenses/)

---------

Signed-off-by: Kai-Uwe Hermann <[email protected]>
  • Loading branch information
hikinggrass authored Nov 25, 2024
1 parent 6960056 commit 51ef0f9
Show file tree
Hide file tree
Showing 9 changed files with 81 additions and 20 deletions.
2 changes: 1 addition & 1 deletion ev-dev-tools/src/ev_cli/__init__.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
"""EVerest command line utility."""
__version__ = '0.4.2'
__version__ = '0.4.3'
41 changes: 31 additions & 10 deletions ev-dev-tools/src/ev_cli/ev.py
Original file line number Diff line number Diff line change
Expand Up @@ -256,13 +256,25 @@ def generate_module_loader_files(rel_mod_dir, output_dir):
return loader_files


def generate_module_files(rel_mod_dir, update_flag):
def generate_module_files(rel_mod_dir, update_flag, licenses):
(_, _, mod) = rel_mod_dir.rpartition('/')

mod_files = {'core': [], 'interfaces': [], 'docs': []}
mod_path = work_dir / f'modules/{rel_mod_dir}/manifest.yaml'
mod_def = helpers.load_validated_module_def(mod_path, validators['module'])

default_license_dir = Path(__file__).parent / 'licenses'
current_license_dir = work_dir / 'licenses'
additional_license_dir = Path(licenses)
license_dirs = [default_license_dir, current_license_dir, additional_license_dir]
license_url = mod_def['metadata']['license']
license_header = helpers.get_license_header(license_dirs, license_url)

if not license_header:
print(f'Could not find license "{license_url}" in {license_dirs}.')
print('Consider providing a additonal custom license directory with --licenses')
exit(1)

tmpl_data = generate_tmpl_data_for_module(mod, mod_def)
output_path = mod_path.parent
# FIXME (aw): we might move the following function into generate_tmp_data_for_module
Expand Down Expand Up @@ -362,6 +374,7 @@ def generate_module_files(rel_mod_dir, update_flag):

if_tmpl_data['info']['blocks'] = helpers.load_tmpl_blocks(
impl_hpp_blocks, output_path / impl_hpp_file, update_flag)
if_tmpl_data['info']['license_header'] = license_header

# FIXME (aw): time stamp should include parent interfaces modification dates
mod_files['interfaces'].append({
Expand All @@ -370,7 +383,8 @@ def generate_module_files(rel_mod_dir, update_flag):
'printable_name': impl_hpp_file,
'content': templates['interface_impl.hpp'].render(if_tmpl_data),
'template_path': Path(templates['interface_impl.hpp'].filename),
'last_mtime': last_mtime
'last_mtime': last_mtime,
'license_header': license_header
})

mod_files['interfaces'].append({
Expand All @@ -379,11 +393,13 @@ def generate_module_files(rel_mod_dir, update_flag):
'printable_name': impl_cpp_file,
'content': templates['interface_impl.cpp'].render(if_tmpl_data),
'template_path': Path(templates['interface_impl.cpp'].filename),
'last_mtime': last_mtime
'last_mtime': last_mtime,
'license_header': license_header
})

cmakelists_file = output_path / 'CMakeLists.txt'
tmpl_data['info']['blocks'] = helpers.load_tmpl_blocks(cmakelists_blocks, cmakelists_file, update_flag)
tmpl_data['info']['license_header'] = license_header
mod_files['core'].append({
'abbr': 'cmakelists',
'path': cmakelists_file,
Expand All @@ -401,7 +417,8 @@ def generate_module_files(rel_mod_dir, update_flag):
'path': mod_hpp_file,
'content': templates['module.hpp'].render(tmpl_data),
'template_path': Path(templates['module.hpp'].filename),
'last_mtime': mod_path.stat().st_mtime
'last_mtime': mod_path.stat().st_mtime,
'license_header': license_header
})

# module.cpp
Expand All @@ -411,7 +428,8 @@ def generate_module_files(rel_mod_dir, update_flag):
'path': mod_cpp_file,
'content': templates['module.cpp'].render(tmpl_data),
'template_path': Path(templates['module.cpp'].filename),
'last_mtime': mod_path.stat().st_mtime
'last_mtime': mod_path.stat().st_mtime,
'license_header': license_header
})

# doc.rst
Expand Down Expand Up @@ -521,7 +539,7 @@ def generate_interface_headers(interface, all_interfaces_flag, output_dir):
def module_create(args):
create_strategy = 'force-create' if args.force else 'create'

mod_files = generate_module_files(args.module, False)
mod_files = generate_module_files(args.module, False, args.licenses)

if args.only == 'which':
helpers.print_available_mod_files(mod_files)
Expand Down Expand Up @@ -551,7 +569,7 @@ def module_update(args):
update_strategy[file_name] = primary_update_strategy

# FIXME (aw): refactor out this only handling and rename it properly
mod_files = generate_module_files(args.module, True)
mod_files = generate_module_files(args.module, True, args.licenses)

if args.only == 'which':
helpers.print_available_mod_files(mod_files)
Expand All @@ -568,13 +586,13 @@ def module_update(args):
helpers.clang_format(args.clang_format_file, file_info)

for file_info in mod_files['core']:
helpers.write_content_to_file(file_info, update_strategy[file_info['abbr']], args.diff)
helpers.write_content_to_file(file_info, update_strategy[file_info['abbr']], args.diff, '', True)

for file_info in mod_files['interfaces']:
if file_info['abbr'].endswith('.hpp'):
helpers.write_content_to_file(file_info, primary_update_strategy, args.diff)
helpers.write_content_to_file(file_info, primary_update_strategy, args.diff, '', True)
else:
helpers.write_content_to_file(file_info, 'update-if-non-existent', args.diff)
helpers.write_content_to_file(file_info, 'update-if-non-existent', args.diff, '', True)


def module_genld(args):
Expand Down Expand Up @@ -734,6 +752,9 @@ def main():
common_parser.add_argument('--schemas-dir', '-sd', type=str,
help='everest framework directory containing the schema definitions (default: ../everest-framework/schemas)',
default=str(Path.cwd() / '../everest-framework/schemas'))
common_parser.add_argument('--licenses', '-lc', type=str,
help='license directory from which ev-cli will attempt to parse custom license texts (default ../licenses)',
default=str(Path.cwd() / '../licenses'))
common_parser.add_argument('--build-dir', '-bd', type=str,
help='everest build directory from which ev-cli will attempt to parse the everest framework schema definitions (default ./build)',
default=str(Path.cwd() / 'build'))
Expand Down
37 changes: 36 additions & 1 deletion ev-dev-tools/src/ev_cli/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -688,7 +688,7 @@ def is_template_newer(file_info) -> Tuple[bool, str]:
return (False, '')


def write_content_to_file(file_info, strategy, only_diff=False, reason = ''):
def write_content_to_file(file_info, strategy, only_diff=False, reason = '', check_license_header=False):
# strategy:
# update: update only if dest older or not existent
# force-update: update, even if dest newer
Expand Down Expand Up @@ -730,6 +730,23 @@ def write_content_to_file(file_info, strategy, only_diff=False, reason = ''):
if not file_dir.exists():
file_dir.mkdir(parents=True, exist_ok=True)

# check if file header is different from license header
if check_license_header:
if 'license_header' in file_info:
original_content = file_path.read_text()
if not original_content.startswith(file_info['license_header']):
# determine likely end of license header
search_terms = ['#ifndef', '#pragma once', '#include']
original_license_header = ''
for search in search_terms:
index = original_content.find(search)
if index >= 0:
original_license_header = original_content[0:index]
break
print(f'Keeping the existing licence header:\n{original_license_header}')
file_info['content'] = file_info['content'].replace(
file_info['license_header'], original_license_header.strip())

file_path.write_text(file_info['content'])


Expand All @@ -740,3 +757,21 @@ def write_content_to_file_and_check_template(file_info, strategy, only_diff=Fals
if newer:
update_strategy = 'force-update'
write_content_to_file(file_info, update_strategy, only_diff, reason)


def get_license_header(license_dirs, license_url):
url_schemas = ['http://', 'https://']
for url_schema in url_schemas:
if license_url.startswith(url_schema):
license_url = license_url.replace(url_schema, '', 1)
license_path = None
for license_dir in license_dirs:
check_license_path = license_dir / license_url
print(f'Checking if license "{check_license_path}" exists...')
if check_license_path.exists():
license_path = check_license_path

if not license_path:
return None
with open(license_path, 'r') as custom_license_file:
return custom_license_file.read().strip()
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright Pionix GmbH and Contributors to EVerest
3 changes: 3 additions & 0 deletions ev-dev-tools/src/ev_cli/templates/helper_macros.j2
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,9 @@ void publish_{{ var.name }}({% if var.json_type != 'null' %}{{ cpp_type(var) }}
// Copyright{% if year_tag %} {{ year_tag }}{% endif %} Pionix GmbH and Contributors to EVerest
{%- endmacro %}

{% macro print_license_header(license) %}
{{ license }}
{%- endmacro %}

{% macro print_template_info(version, title='DO NOT EDIT!', comment_sep='//') %}
{{ comment_sep }}
Expand Down
4 changes: 2 additions & 2 deletions ev-dev-tools/src/ev_cli/templates/interface-Impl.cpp.j2
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{% from "helper_macros.j2" import handle_cmd_signature, print_spdx_line %}
{{ print_spdx_line('Apache-2.0') }}
{% from "helper_macros.j2" import handle_cmd_signature, print_license_header %}
{{ print_license_header(info.license_header) }}

#include "{{ info.class_name}}.hpp"

Expand Down
4 changes: 2 additions & 2 deletions ev-dev-tools/src/ev_cli/templates/interface-Impl.hpp.j2
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{% from "helper_macros.j2" import handle_cmd_signature, print_template_info, insert_block, cpp_type, print_spdx_line %}
{{ print_spdx_line('Apache-2.0') }}
{% from "helper_macros.j2" import handle_cmd_signature, print_template_info, insert_block, cpp_type, print_license_header %}
{{ print_license_header(info.license_header) }}
#ifndef {{ info.hpp_guard }}
#define {{ info.hpp_guard }}

Expand Down
4 changes: 2 additions & 2 deletions ev-dev-tools/src/ev_cli/templates/module.cpp.j2
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{% from "helper_macros.j2" import print_spdx_line %}
{{ print_spdx_line('Apache-2.0') }}
{% from "helper_macros.j2" import print_license_header %}
{{ print_license_header(info.license_header) }}
#include "{{ info.module_header }}"

namespace module {
Expand Down
4 changes: 2 additions & 2 deletions ev-dev-tools/src/ev_cli/templates/module.hpp.j2
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{% from "helper_macros.j2" import print_template_info, insert_block, cpp_type, print_spdx_line %}
{{ print_spdx_line('Apache-2.0') }}
{% from "helper_macros.j2" import print_template_info, insert_block, cpp_type, print_license_header %}
{{ print_license_header(info.license_header) }}
#ifndef {{ info.hpp_guard }}
#define {{ info.hpp_guard }}

Expand Down

0 comments on commit 51ef0f9

Please sign in to comment.