Skip to content

gh70 - xts demo - #72

Merged
zghp merged 5 commits into
developfrom
feature/gh70-xts-demo
Aug 12, 2026
Merged

gh70 - xts demo#72
zghp merged 5 commits into
developfrom
feature/gh70-xts-demo

Conversation

@zghp

@zghp zghp commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

No description provided.

@zghp zghp self-assigned this Jun 22, 2026
Copilot AI lite review requested due to automatic review settings June 22, 2026 12:20
@zghp
zghp requested a review from a team as a code owner June 22, 2026 12:20
@zghp zghp added the enhancement New feature or request label Jun 22, 2026
@github-actions

Copy link
Copy Markdown


Thank you for your submission, we really appreciate it. Like many open-source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution. You can sign the CLA by just posting a Pull Request Comment same as the below format.


I have read the CLA Document and I hereby sign the CLA


zghp seems not to be a GitHub user. You need a GitHub account to be able to sign the CLA. If you have already a GitHub account, please add the email address used for this commit to your account.
You can retrigger this bot by commenting recheck in this Pull Request. Posted by the CLA Assistant Lite bot.

@zghp zghp linked an issue Jun 22, 2026 that may be closed by this pull request
@zghp
zghp requested a review from TB-1993 June 22, 2026 12:24
@rdkcmf-jenkins

Copy link
Copy Markdown
Contributor

b'## Blackduck scan failure details

Summary: 0 violations, 0 files pending approval, 1 file pending identification.

  • Protex Server Path: /home/blackduck/github/xts_core/72/rdkcentral/xts_core

  • Commit: 6c24028

Report detail: gist'

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds an xts demo built-in command intended to walk first-time users through alias setup and running a sample command, along with test coverage and README updates.

Changes:

  • Adds a demo built-in path in XTS._parse_first_arg() and an interactive _run_demo() flow.
  • Adds a pytest that exercises the demo flow via monkeypatching and a fake YamlRunner.
  • Documents the new xts demo command in the README.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 9 comments.

File Description
src/xts_core/xts.py Adds demo built-in handling, interactive demo flow, and a YamlRunner-compatibility fallback.
test/test_xts_all_cases.py Adds an end-to-end-ish test for xts demo and adjusts import path handling.
README.md Documents the new interactive demo command.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/xts_core/xts.py
Comment thread src/xts_core/xts.py Outdated
Comment thread src/xts_core/xts.py Outdated
Comment thread src/xts_core/xts.py Outdated
Comment thread src/xts_core/xts.py Outdated
Comment on lines +282 to +284
info('Welcome to the XTS interactive demo!')
info('This demo will add an alias, show the alias list, and run all example commands.')
print()
Comment thread src/xts_core/xts.py Outdated
Comment thread src/xts_core/xts.py Outdated
Comment thread test/test_xts_all_cases.py
Comment thread README.md
@rdkcmf-jenkins

Copy link
Copy Markdown
Contributor

b'## Blackduck scan failure details

Summary: 0 violations, 0 files pending approval, 1 file pending identification.

  • Protex Server Path: /home/blackduck/github/xts_core/72/rdkcentral/xts_core

  • Commit: 6c24028

Report detail: gist'

@rdkcmf-jenkins

Copy link
Copy Markdown
Contributor

b'## WARNING: A Blackduck scan failure has been waived

A prior failure has been upvoted

  • Upvote reason: OK

  • Commit: 6c24028
    '

Comment thread src/xts_core/xts.py Outdated
Comment thread src/xts_core/xts.py Outdated
Comment thread src/xts_core/xts.py Outdated
Copilot AI review requested due to automatic review settings August 3, 2026 11:22
@zghp
zghp force-pushed the feature/gh70-xts-demo branch from 6c24028 to e07a989 Compare August 3, 2026 11:22

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated no new comments.

Suppressed comments (12)

src/xts_core/xts.py:8

  • The Apache 2.0 license header was partially removed and replaced by whitespace (the copyright + license grant lines are missing). This can create compliance/attribution issues and should be restored to the prior header format.
# * If not stated otherwise in this file or this component's LICENSE file the
# * following copyright and licenses apply:
# *
        
# * You may obtain a copy of the License at

src/xts_core/xts.py:403

  • _find_demo_example_config() is currently unused by the demo implementation (the demo uses a public URL), and the only reference is in the new test via monkeypatch. This leaves dead code in the CLI and makes the test patching misleading. Either wire this into the demo flow, or delete it and update the test accordingly.
    def _find_demo_example_config(self) -> str:
        """Locate the example XTS config used by the interactive demo."""
        package_root = Path(__file__).resolve().parents[2]
        example_config = package_root / 'examples' / 'hello_world.xts'
        if example_config.exists():
            return str(example_config)

src/xts_core/xts.py:417

  • _collect_command_paths() is newly added but never called (no references outside the method itself). This adds maintenance surface without functionality; remove it until it’s needed.
    def _collect_command_paths(self, section: dict, prefix: list[str] | None = None) -> list[list[str]]:
        """Recursively collect leaf command paths from a command section."""
        prefix = prefix or []
        paths: list[list[str]] = []

test/test_xts_all_cases.py:131

  • The asserted demo output strings don’t match the current demo implementation (exclamation in welcome message, different section text/numbering, xts alias ... commands, alias name example, and no refresh section). These assertions will fail even if the demo works.
        assert 'Welcome to the XTS interactive demo' in output
        assert 'Section 1: Alias help command.' in output
        assert 'Command: xts --alias --help' in output
        assert 'Section 2: Add a demo alias for the example file.' in output
        assert 'Command: xts --alias --add' in output
        assert 'Section 3: List available aliases.' in output
        assert 'Command: xts --alias --list' in output
        assert 'Section 4: Run the demo alias command.' in output
        assert 'Command: xts demo-example run hello_world' in output
        assert 'Section 5: Remove the demo alias.' in output
        assert 'Command: xts --alias --remove demo-example' in output
        assert 'Section 6: Refresh the demo alias.' in output
        assert 'Command: xts --alias --refresh demo-example' in output
        assert 'demo-example ->' in output
        assert 'Removed alias: demo-example' in output
        assert 'Demo finished. You can now add your own aliases' in output

src/xts_core/demo.py:100

  • This except handler intends to recover, but utils.error() raises SystemExit(1) and will exit the demo. Use a non-exiting logger (e.g., warning()/info()) if you want the demo to proceed after a command failure.
    except SystemExit:
        pass
    except Exception as exc:
        error(f'Failed to run demo alias command: {exc}')

src/xts_core/demo.py:109

  • Same issue as earlier sections: utils.error() raises SystemExit(1), so this error path exits the demo immediately instead of continuing to the final message. Use a non-exiting logger if the demo should continue.
    try:
        run_demo_alias_builtin(['remove', alias_name])
    except Exception as exc:
        error(f'Failed to remove demo alias: {exc}')

src/xts_core/xts.py:38

  • json is imported but not used anywhere in this module (only referenced in a docstring path). Removing it avoids lint noise and keeps imports minimal.

This issue also appears on line 398 of the same file.

import json
from pathlib import Path

test/test_xts_all_cases.py:108

  • This test patches functions/classes that the demo code path doesn’t use (the demo logic lives in xts_core.demo, not xts_core.xts, and it doesn’t call add_alias_from_input / refresh_alias). As written, the test is likely to hit real alias logic and won’t stub out the YamlRunner used by the demo.
    monkeypatch.setattr('xts_core.xts_alias.add_alias_from_input', lambda path, name: [(name, str(path))])
    monkeypatch.setattr('xts_core.xts_alias.list_aliases', lambda: None)
    monkeypatch.setattr('xts_core.xts_alias.refresh_alias', lambda name: (name, str(demo_file)))
    monkeypatch.setattr('xts_core.xts_alias.remove_alias', lambda name: True)

    class FakeRunner:
        def __init__(self, *args, **kwargs):
            pass

        def run(self, args):
            assert args == ['run', 'hello_world']
            return (None, None, [0])

    monkeypatch.setattr('xts_core.xts.YamlRunner', FakeRunner)
    monkeypatch.setattr('builtins.input', lambda prompt='': '')
    monkeypatch.setattr('xts_core.xts.XTS._find_demo_example_config', lambda self: str(demo_file))

README.md:147

  • README says the demo adds an alias from examples/hello_world.xts, but the implementation uses a public raw GitHub URL. Update this sentence to match actual behavior so users aren’t misled.
It will add a sample alias from `examples/hello_world.xts`, list the alias, and execute the example `hello_world` command.

src/xts_core/xts.py:375

  • The try: block after the match in run() is dead code: every match branch raises SystemExit (directly or via _run_yaml_runner() / _run_validate_command()), so this block will never run. If it did run, it would call yaml_runner.run(args) where args is a dict (from vars(args)), not an argv list, so it would likely fail. Please remove this duplicated runner logic to avoid confusion.
        try:
            try:
                yaml_runner = YamlRunner(
                    self._command_sections,
                    program='xts',

src/xts_core/demo.py:60

  • utils.error() raises SystemExit(1), so calling it inside this except block will terminate the demo immediately (the code below will never run). If the intent is to continue the demo after a failure, use a non-exiting logger (e.g., warning() / info()) or catch SystemExit explicitly.

This issue also appears in the following locations of the same file:

  • line 97
  • line 106
    try:
        run_demo_alias_builtin(['add', '--name', alias_name, example_url])
    except Exception as exc:
        error(f'Failed to add demo alias: {exc}')

src/xts_core/demo.py:70

  • utils.error() raises SystemExit(1), so the return immediately after this call is unreachable. Decide whether demo resolution failure should abort (then remove the return) or should be non-fatal (then replace error(...) with a non-exiting logger and keep return).
    resolved_xts_path = xts_alias.resolve_alias_to_xts_path(alias_name)
    if resolved_xts_path is None:
        error(f'Failed to resolve alias for demo execution: {alias_name}')
        return

Copilot AI review requested due to automatic review settings August 7, 2026 10:39

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated no new comments.

Suppressed comments (8)

test/test_xts_all_cases.py:120

  • The asserted demo output (section titles and command strings) does not match what src/xts_core/demo.py currently prints (e.g., it uses Section 1: Show top-level help for XTS. and COMMAND TO EXECUTE: and xts alias ..., not the --alias strings asserted here). This will cause the test to fail even when the demo works.
        assert 'Welcome to the XTS interactive demo' in output
        assert 'Section 1: Alias help command.' in output
        assert 'Command: xts --alias --help' in output
        assert 'Section 2: Add a demo alias for the example file.' in output
        assert 'Command: xts --alias --add' in output

src/xts_core/xts.py:389

  • _find_demo_example_config() is annotated to return str but falls off the end after calling error(...), returning None. If this helper is used, that will cause type/logic errors downstream; it should raise/exit or return a valid string.
        error(
            'Could not locate demo example config. Ensure examples/hello_world.xts exists.'
        )

src/xts_core/demo.py:6

  • New module is missing the standard Apache 2.0 header/shebang that other src/xts_core/*.py modules include (for example src/xts_core/utils.py:1-22). This breaks the established file header convention in this repo.
"""Reusable interactive demo helpers for the XTS CLI."""

import sys

import rich
from yaml_runner import YamlRunner

src/xts_core/demo.py:86

  • alias_name = 'example' will overwrite an existing user alias named example because xts_alias.add_alias() unconditionally updates the mapping. Using a less collision-prone name makes the demo safer to run on existing setups.
    alias_name = 'example'

test/test_xts_all_cases.py:108

  • The demo test is patching xts_core.xts_alias.*, xts_core.xts.YamlRunner, and XTS._find_demo_example_config(), but the implemented demo flow lives in xts_core.demo and calls run_demo_alias_builtin(), _run_xts_help_command(), xts_core.demo.YamlRunner, and xts_core.demo.xts_alias.resolve_alias_to_xts_path(). As written, this test will execute real alias/network logic and won't reliably control the demo behavior.

This issue also appears on line 116 of the same file.

    monkeypatch.setattr('xts_core.xts_alias.add_alias_from_input', lambda path, name: [(name, str(path))])
    monkeypatch.setattr('xts_core.xts_alias.list_aliases', lambda: None)
    monkeypatch.setattr('xts_core.xts_alias.refresh_alias', lambda name: (name, str(demo_file)))
    monkeypatch.setattr('xts_core.xts_alias.remove_alias', lambda name: True)

    class FakeRunner:
        def __init__(self, *args, **kwargs):
            pass

        def run(self, args):
            assert args == ['run', 'hello_world']
            return (None, None, [0])

    monkeypatch.setattr('xts_core.xts.YamlRunner', FakeRunner)
    monkeypatch.setattr('builtins.input', lambda prompt='': '')
    monkeypatch.setattr('xts_core.xts.XTS._find_demo_example_config', lambda self: str(demo_file))

src/xts_core/xts.py:10

  • Trailing whitespace was introduced into the Apache header line; this creates noisy diffs and can trip whitespace checks.
# * you may not use this file except in compliance with the License. 

src/xts_core/xts.py:42

  • import json is added but not used anywhere in this module (only referenced in a docstring). Unused imports add lint noise and slow startup slightly.
import re
import shlex
import sys
import json
from pathlib import Path

README.md:147

  • README says the demo adds an alias from the local examples/hello_world.xts, but the implementation in src/xts_core/demo.py adds from a public GitHub raw URL. This is user-facing documentation drift.
It will add a sample alias from `examples/hello_world.xts`, list the alias, and execute the example `hello_world` command.

Comment thread src/xts_core/xts.py Outdated
Comment thread src/xts_core/xts.py Outdated
Comment thread src/xts_core/xts.py Outdated
Comment thread src/xts_core/xts.py Outdated
Copilot AI review requested due to automatic review settings August 12, 2026 07:15

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated no new comments.

Suppressed comments (10)

test/test_xts_all_cases.py:108

  • This test currently patches xts_core.xts.YamlRunner, but xts demo uses YamlRunner imported in xts_core.demo, so the fake runner won’t be used. Also, run_demo() resolves the alias via resolve_alias_to_xts_path(), but the test’s add_alias_from_input stub doesn’t persist an alias, so resolution will fail unless patched.
    monkeypatch.setattr('xts_core.xts_alias.add_alias_from_input', lambda path, name: [(name, str(path))])
    monkeypatch.setattr('xts_core.xts_alias.list_aliases', lambda: None)
    monkeypatch.setattr('xts_core.xts_alias.refresh_alias', lambda name: (name, str(demo_file)))
    monkeypatch.setattr('xts_core.xts_alias.remove_alias', lambda name: True)

    class FakeRunner:
        def __init__(self, *args, **kwargs):
            pass

        def run(self, args):
            assert args == ['run', 'hello_world']
            return (None, None, [0])

    monkeypatch.setattr('xts_core.xts.YamlRunner', FakeRunner)
    monkeypatch.setattr('builtins.input', lambda prompt='': '')
    monkeypatch.setattr('xts_core.xts.XTS._find_demo_example_config', lambda self: str(demo_file))

test/test_xts_all_cases.py:131

  • The assertions in this test don’t match the current demo output/flow: the demo uses xts alias ... subcommands (not --alias flags), prints commands prefixed with COMMAND TO EXECUTE:, uses alias name demo-example (after the suggested fix), and does not include remove/refresh sections. As written, this test will fail even if the demo works.
    with patch('sys.stdout', new_callable=StringIO) as mock_stdout:
        sys.argv = ['xts', 'demo']
        from xts_core.xts import XTS
        with pytest.raises(SystemExit) as excinfo:
            XTS().run()
        assert excinfo.value.code == 0
        output = mock_stdout.getvalue()
        assert 'Welcome to the XTS interactive demo' in output
        assert 'Section 1: Alias help command.' in output
        assert 'Command: xts --alias --help' in output
        assert 'Section 2: Add a demo alias for the example file.' in output
        assert 'Command: xts --alias --add' in output
        assert 'Section 3: List available aliases.' in output
        assert 'Command: xts --alias --list' in output
        assert 'Section 4: Run the demo alias command.' in output
        assert 'Command: xts demo-example run hello_world' in output
        assert 'Section 5: Remove the demo alias.' in output
        assert 'Command: xts --alias --remove demo-example' in output
        assert 'Section 6: Refresh the demo alias.' in output
        assert 'Command: xts --alias --refresh demo-example' in output
        assert 'demo-example ->' in output
        assert 'Removed alias: demo-example' in output
        assert 'Demo finished. You can now add your own aliases' in output

README.md:147

  • README says the demo adds an alias from the local examples/hello_world.xts, but the implementation adds it from a public GitHub raw URL. Update the docs to reflect the actual behavior (and the alias name used by the demo) to avoid confusing users.
A new interactive demo command is available to guide first-time users through alias setup and execution:

```sh
xts demo

It will add a sample alias from examples/hello_world.xts, list the alias, and execute the example hello_world command.

**src/xts_core/demo.py:86**
* The demo hard-codes `alias_name = 'example'`, and `xts_alias.add_alias()` overwrites existing aliases. Running `xts demo` would silently replace a user’s existing `example` alias if they already have one configured.
alias_name = 'example'
**src/xts_core/demo.py:1**
* This new module is missing the project’s standard Apache 2.0 file header (most existing Python modules include it, e.g. src/xts_core/utils.py:1-22). Add the header to keep licensing and file formatting consistent.

"""Reusable interactive demo helpers for the XTS CLI."""

**src/xts_core/xts.py:11**
* Trailing whitespace was introduced in the Apache license header line; this tends to fail formatting/lint checks and is easy to avoid.

* Licensed under the Apache License, Version 2.0 (the "License");

* you may not use this file except in compliance with the License.

* You may obtain a copy of the License at

**src/xts_core/xts.py:387**
* `_find_demo_example_config()` is not called anywhere (only monkeypatched in the new test). Since the demo now pulls the example from a URL, this method (and the new `Path` import) looks like dead code and will add maintenance overhead.
def _find_demo_example_config(self) -> str:
    """Locate the example XTS config used by the interactive demo."""
    package_root = Path(__file__).resolve().parents[2]
    example_config = package_root / 'examples' / 'hello_world.xts'
    if example_config.exists():
        return str(example_config)

    alt_example = Path.cwd() / 'examples' / 'hello_world.xts'
    if alt_example.exists():
        return str(alt_example)

    error(
        'Could not locate demo example config. Ensure examples/hello_world.xts exists.'
    )
**src/xts_core/xts.py:395**
* There are trailing spaces at EOF after `main()` which can trigger whitespace checks. Remove the extra whitespace-only line.

if name == "main":
main()

**src/xts_core/demo.py:84**
* The demo fetch URL targets `refs/heads/master`, but this repo’s default branch appears to be `main` (diff base is `main`). Using `master` will likely 404 and break the demo for users.

This issue also appears on line 85 of the same file.
example_url = (
    'https://raw.githubusercontent.com/rdkcentral/xts_core/refs/heads/master/'
    'examples/hello_world.xts'
)
**test/test_xts_all_cases.py:87**
* This test calls the real alias built-in (`xts alias ...`) which reads/writes `~/.xts/*`. Add the existing `mock_alias_config` fixture so the demo test runs isolated from the developer/CI environment.

This issue also appears in the following locations of the same file:
- line 92
- line 109

def test_demo_builtin_runs_interactive_demo(monkeypatch, tmp_path):
"""Test that xts demo runs the interactive demo flow."""
demo_file = tmp_path / 'hello_world.xts'

</details>

Copilot AI review requested due to automatic review settings August 12, 2026 09:35

@TB-1993 TB-1993 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, ship it!

@zghp
zghp merged commit 2c9206b into develop Aug 12, 2026
3 of 4 checks passed
@zghp
zghp deleted the feature/gh70-xts-demo branch August 12, 2026 09:40
@github-actions github-actions Bot locked and limited conversation to collaborators Aug 12, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feature: xts demo

4 participants