Skip to content
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
47 changes: 41 additions & 6 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,9 @@ jobs:
strategy:
fail-fast: false
matrix:
# NOTE: Testing of the Windows targets are currently disabled because
# the test script is simply not ready for it.
# NOTE: Full testsuite on Windows is disabled because the test script
# requires Linux kernel source tree. However, headless mode tests
# are now enabled for Windows.
target:
# Python 3.12
- python: '3.12'
Expand All @@ -28,9 +29,10 @@ jobs:
- python: '3.12'
os: macOS
builder: macos-15
# - python: '3.12'
# os: Windows
# builder: windows-2022
- python: '3.12'
os: Windows
builder: windows-2022
headless-only: true

steps:
- name: Set up environment
Expand Down Expand Up @@ -58,6 +60,8 @@ jobs:
pip install --user setuptools wheel

- name: Check out Linux source code
# Skip for Windows (headless-only mode)
if: ${{ matrix.target.headless-only != true }}
uses: actions/checkout@v5
# On Windows, checkout of 'aux.c' is expected to fail because ... Windows.
continue-on-error: true
Expand All @@ -68,12 +72,43 @@ jobs:
- name: Check out Kconfiglib source code
uses: actions/checkout@v5
with:
path: Kconfiglib
# Windows (headless-only): checkout to root directory
# Linux/macOS (full test): checkout to Kconfiglib subdirectory
path: ${{ matrix.target.headless-only && '.' || 'Kconfiglib' }}

- name: Apply Linux Kconfig Makefile patch
# Skip for Windows (headless-only mode)
if: ${{ matrix.target.headless-only != true }}
run: |
git apply Kconfiglib/makefile.patch

- name: Run testsuite
# Skip for Windows (headless-only mode)
if: ${{ matrix.target.headless-only != true }}
run: |
Kconfiglib/tests/reltest python

- name: Test headless mode
# Use root dir for Windows, Kconfiglib subdir for Linux/macOS
working-directory: ${{ matrix.target.headless-only && '.' || 'Kconfiglib' }}
run: |
python << 'EOF'
from kconfiglib import Kconfig
import menuconfig
print('Testing headless mode...')
kconf = Kconfig('examples/Kmenuconfig')
menuconfig.menuconfig(kconf, headless=True)
print('Headless mode test passed')
EOF

- name: Install windows-curses (Windows only)
if: matrix.target.os == 'Windows'
run: |
pip install windows-curses

- name: Test menuconfig import (Windows Python 3.12)
if: matrix.target.os == 'Windows'
# Use root dir for Windows (headless-only mode)
working-directory: ${{ matrix.target.headless-only && '.' || 'Kconfiglib' }}
run: |
python -c "import menuconfig; print('menuconfig import successful')"
15 changes: 13 additions & 2 deletions menuconfig.py
Original file line number Diff line number Diff line change
Expand Up @@ -729,15 +729,22 @@ def _main():
menuconfig(standard_kconfig(__doc__))


def menuconfig(kconf):
def menuconfig(kconf, headless=False):
"""
Launches the configuration interface, returning after the user exits.

kconf:
Kconfig instance to be configured

headless:
If True, run in headless mode without launching the terminal interface.
This is useful for testing, CI/CD pipelines, and automated configuration
processing. In headless mode, the function only loads the configuration
and returns immediately without user interaction.
"""
# Import curses at runtime to avoid issues in headless environments
_ensure_curses()
if not headless:
_ensure_curses()

global _kconf
global _conf_filename
Expand Down Expand Up @@ -785,6 +792,10 @@ def menuconfig(kconf):
if _CHANGE_C_LC_CTYPE_TO_UTF8:
_change_c_lc_ctype_to_utf8()

# In headless mode, just load the configuration and return
if headless:
return

# Get rid of the delay between pressing ESC and jumping to the parent menu,
# unless the user has set ESCDELAY (see ncurses(3)). This makes the UI much
# smoother to work with.
Expand Down