Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[nrf noup] ZAP west command improvements #445

Merged
merged 1 commit into from
May 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 48 additions & 18 deletions scripts/west/zap_common.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,29 +12,49 @@
import tempfile
import wget

from collections import deque
from pathlib import Path
from typing import Tuple
from zipfile import ZipFile

from west import log

MATTER_PATH = Path(__file__).parents[2]
DEFAULT_MATTER_PATH = Path(__file__).parents[2]


def find_zap(root: Path = Path.cwd(), max_depth: int = 1):
def find_zap(root: Path = Path.cwd(), max_depth: int = 2):
"""
Find *.zap file in the given directory or its subdirectories.
"""
subdirs = []
for name in root.iterdir():
if name.is_file() and (name.suffix.lower() == '.zap'):
return root / name
if name.is_dir() and (max_depth > 0):
subdirs.append(name)
for subdir in subdirs:
if zap := find_zap(root / subdir, max_depth - 1):
return zap
return None
zap_files = []
search_dirs = deque()
search_dirs.append((root, max_depth))

while search_dirs:
search_dir, max_depth = search_dirs.popleft()

for name in search_dir.iterdir():
if name.is_file() and (name.suffix.lower() == '.zap'):
zap_files.append(search_dir / name)
continue
if name.is_dir() and (max_depth > 0):
search_dirs.append((search_dir / name, max_depth - 1))

# At most one ZAP file found in the selected location, return immediately.
if len(zap_files) <= 1:
return zap_files[0] if zap_files else None

# Otherwise, ask a user to choose the ZAP file to edit.
for i, zap_file in enumerate(zap_files):
print(f'{i}. {zap_file.relative_to(root)}')

while True:
try:
maxind = len(zap_files) - 1
prompt = f'Select file to edit (0-{maxind}): '
return zap_files[int(input(prompt))]
except Exception:
pass


def existing_file_path(arg: str) -> Path:
Expand All @@ -47,6 +67,16 @@ def existing_file_path(arg: str) -> Path:
raise argparse.ArgumentTypeError(f'invalid file path: \'{arg}\'')


def existing_dir_path(arg: str) -> Path:
"""
Helper function to validate directory path argument.
"""
p = Path(arg)
if p.is_dir():
return p
raise argparse.ArgumentTypeError(f'invalid directory path: \'{arg}\'')


class ZapInstaller:
INSTALL_DIR = Path('.zap-install')
ZAP_URL_PATTERN = 'https://github.com/project-chip/zap/releases/download/v%04d.%02d.%02d-nightly/%s.zip'
Expand Down Expand Up @@ -171,15 +201,15 @@ def update_zap_if_needed(self) -> None:
recommended_version = self.get_recommended_version()
current_version = self.get_current_version()

if current_version == recommended_version:
log.inf('ZAP is up to date: {0}.{1}.{2}'.format(*recommended_version))
return
log.inf(f'ZAP installation directory: {self.install_path}')

if current_version:
log.inf('Found ZAP version: {0}.{1}.{2}'.format(*current_version))
verdict = 'up to date' if current_version == recommended_version else 'outdated'
log.inf('Found ZAP {}.{}.{} ({})'.format(*current_version, verdict))

log.inf('Installing ZAP version: {0}.{1}.{2}'.format(*recommended_version))
self.install_zap(recommended_version)
if current_version != recommended_version:
log.inf('Installing ZAP {}.{}.{}'.format(*recommended_version))
self.install_zap(recommended_version)

@staticmethod
def set_exec_permission(path: Path) -> None:
Expand Down
10 changes: 6 additions & 4 deletions scripts/west/zap_generate.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
from west import log
from west.commands import CommandError, WestCommand

from zap_common import existing_file_path, find_zap, ZapInstaller, MATTER_PATH
from zap_common import existing_file_path, existing_dir_path, find_zap, ZapInstaller, DEFAULT_MATTER_PATH


class ZapGenerate(WestCommand):
Expand All @@ -35,6 +35,8 @@ def do_add_parser(self, parser_adder):
help='Path to data model configuration file (*.zap)')
parser.add_argument('-o', '--output', type=Path,
help='Path where to store the generated files')
parser.add_argument('-m', '--matter-path', type=existing_dir_path,
default=DEFAULT_MATTER_PATH, help='Path to Matter SDK')
return parser

def do_run(self, args, unknown_args):
Expand All @@ -51,10 +53,10 @@ def do_run(self, args, unknown_args):
else:
output_path = zap_file_path.parent / "zap-generated"

app_templates_path = MATTER_PATH / "src/app/zap-templates/app-templates.json"
zap_generate_path = MATTER_PATH / "scripts/tools/zap/generate.py"
app_templates_path = args.matter_path / "src/app/zap-templates/app-templates.json"
zap_generate_path = args.matter_path / "scripts/tools/zap/generate.py"

zap_installer = ZapInstaller(MATTER_PATH)
zap_installer = ZapInstaller(args.matter_path)
zap_installer.update_zap_if_needed()

# make sure that the generate.py script uses the proper zap_cli binary (handled by west)
Expand Down
12 changes: 7 additions & 5 deletions scripts/west/zap_gui.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@

import argparse

from pathlib import Path
from textwrap import dedent

from zap_common import existing_file_path, find_zap, ZapInstaller, MATTER_PATH
from west.commands import WestCommand

from zap_common import existing_file_path, existing_dir_path, find_zap, ZapInstaller, DEFAULT_MATTER_PATH


class ZapGui(WestCommand):

Expand All @@ -33,6 +33,8 @@ def do_add_parser(self, parser_adder):
help='Path to data model configuration file (*.zap)')
parser.add_argument('-j', '--zcl-json', type=existing_file_path,
help='Path to data model definition file (zcl.json)')
parser.add_argument('-m', '--matter-path', type=existing_dir_path,
default=DEFAULT_MATTER_PATH, help='Path to Matter SDK')
return parser

def do_run(self, args, unknown_args):
Expand All @@ -44,11 +46,11 @@ def do_run(self, args, unknown_args):
if args.zcl_json:
zcl_json_path = args.zcl_json.absolute()
else:
zcl_json_path = MATTER_PATH / 'src/app/zap-templates/zcl/zcl.json'
zcl_json_path = args.matter_path / 'src/app/zap-templates/zcl/zcl.json'

app_templates_path = MATTER_PATH / 'src/app/zap-templates/app-templates.json'
app_templates_path = args.matter_path / 'src/app/zap-templates/app-templates.json'

zap_installer = ZapInstaller(Path(MATTER_PATH))
zap_installer = ZapInstaller(args.matter_path)
zap_installer.update_zap_if_needed()
zap_cache_path = zap_installer.get_install_path() / ".zap"

Expand Down
Loading