Commit 6169269d authored by Noah Pendleton's avatar Noah Pendleton Committed by Benjamin Cabé
Browse files

west: blobs: fetch `--allow-regex` filter



When building in CI for specific SOCs, it's useful to only have `west blobs
fetch` pull a selected set of blob objects. This is especially helpful on
`hal_espressif`, which currently has 78 blob objects.

Add a `--allow-regex` arg to the `west blobs fetch` subcommand to filter
only specified blobs, for example:

```bash
# only download esp32 blobs, skip the other variants
❯ west blobs fetch hal_espressif --allow-regex 'lib/esp32/.*'
```

Also, replace all `str.format()` invocations with f-strings per review
feedback.

Signed-off-by: default avatarNoah Pendleton <noah.pendleton@gmail.com>
parent 2ee5a8d6
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -214,6 +214,12 @@ Additionally the tool allows you to specify the modules you want to list,
fetch or clean blobs for by typing the module names as a command-line
parameter.

The argument ``--allow-regex`` can be passed ``west blobs fetch`` to restrict
the specific blobs that are fetched, by passing a regular expression::

  # For example, only download esp32 blobs, skip the other variants
  west blobs fetch hal_espressif --allow-regex 'lib/esp32/.*'

.. _west-twister:

Twister wrapper: ``west twister``
+22 −6
Original line number Diff line number Diff line
@@ -4,6 +4,7 @@

import argparse
import os
import re
import sys
import textwrap
from pathlib import Path
@@ -78,6 +79,13 @@ class Blobs(WestCommand):
                                    see FORMAT STRINGS below''')

        group = parser.add_argument_group('west blobs fetch options')
        group.add_argument(
            '-l',
            '--allow-regex',
            help='''Regex pattern to apply to the blob local path.
                    Only local paths matching this regex will be fetched.
                    Note that local paths are relative to the module directory''',
        )
        group.add_argument('-a', '--auto-accept', action='store_true',
                            help='''auto accept license if the fetching needs click-through''')

@@ -127,7 +135,7 @@ class Blobs(WestCommand):
    # Compare the checksum of a file we've just downloaded
    # to the digest in blob metadata, warn user if they differ.
    def verify_blob(self, blob) -> bool:
        self.dbg('Verifying blob {module}: {abspath}'.format(**blob))
        self.dbg(f"Verifying blob {blob['module']}: {blob['abspath']}")

        status = zephyr_module.get_blob_status(blob['abspath'], blob['sha256'])
        if status == zephyr_module.BLOB_OUTDATED:
@@ -154,9 +162,17 @@ class Blobs(WestCommand):
        blobs = self.get_blobs(args)
        for blob in blobs:
            if blob['status'] == zephyr_module.BLOB_PRESENT:
                self.dbg('Blob {module}: {abspath} is up to date'.format(**blob))
                self.dbg(f"Blob {blob['module']}: {blob['abspath']} is up to date")
                continue
            self.inf('Fetching blob {module}: {abspath}'.format(**blob))

            # if args.allow_regex is set, use it to filter the blob by path
            if args.allow_regex and not re.match(args.allow_regex, blob['path']):
                self.dbg(
                    f"Blob {blob['module']}: {blob['abspath']} does not match regex "
                    f"'{args.allow_regex}', skipping"
                )
                continue
            self.inf(f"Fetching blob {blob['module']}: {blob['abspath']}")

            if blob['click-through'] and not args.auto_accept:
                while True:
@@ -196,13 +212,13 @@ class Blobs(WestCommand):
        blobs = self.get_blobs(args)
        for blob in blobs:
            if blob['status'] == zephyr_module.BLOB_NOT_PRESENT:
                self.dbg('Blob {module}: {abspath} not in filesystem'.format(**blob))
                self.dbg(f"Blob {blob['module']}: {blob['abspath']} not in filesystem")
                continue
            self.inf('Deleting blob {module}: {status} {abspath}'.format(**blob))
            self.inf(f"Deleting blob {blob['module']}: {blob['status']} {blob['abspath']}")
            blob['abspath'].unlink()

    def do_run(self, args, _):
        self.dbg(f'subcmd: \'{args.subcmd[0]}\' modules: {args.modules}')
        self.dbg(f"subcmd: '{args.subcmd[0]}' modules: {args.modules}")

        subcmd = getattr(self, args.subcmd[0])