Skip to content

Commit

Permalink
[nrf noup] ZAP west command improvements
Browse files Browse the repository at this point in the history
1. If multiple ZAP files are detected in the given location,
   ask a user to choose the one to edit.
2. Allow to provide a Matter SDK path to enable using the
   commands with the upstream repo.

Signed-off-by: Damian Krolik <damian.krolik@nordicsemi.no>
  • Loading branch information
Damian-Nordic committed May 24, 2024
1 parent 4171153 commit 99505eb
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 27 deletions.
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

0 comments on commit 99505eb

Please sign in to comment.