[PATCH v2 00/24] tools: Support uploading tools to PyPi for use with pip

Some of the tools in U-Boot are useful beyond just U-Boot. For example, patman can be used to work with Linux and other projects which use mailing lists (and patchwork) for patch submissions. Binman can be used to package firmware for any project, even though it is heavily slanted towards U-Boot so far.
While patman has a setup script which is easy to use, binman is a little more complicated, since it has dependencies, in particular pylibfdt
It would be better if we could put all the tools on PyPi.
This series adds a script for uploading tools. It makes it easier to update PyPi from time to time, when new features appear.
U-Boot uses tools/patman as a common library of Python functions. For this to work with PyPi it is easier to split these into a separate library, used by patman as well. This series creates a new 'u_boot_pylib' package for this purpose.
Unfortunately, the U-Boot version of concurrencytest has some local patches. To avoid dependency issues it seems better to revert these and rely on the upstream package[1], although note that it is not actually installed.
[1] Which unfortunately may be dead but perhaps we could request a new maintainer?
Changes in v2: - Add a patch to hide the test options unless test code is available - Add new patch to avoid importing test_checkpatch before it is needed - Add new patch to use importlib to find the help - Add patch to fix use of a type as a variable - Add patch to split out the main code into a function - Drop test files - Fix removable of the /tmp dir - Quite a few updates to make things work with the new names - Rename the package to patch-manager - Update the cover letter
Simon Glass (24): binman: Avoid unwanted output in testFitFirmwareLoadables() Revert "patman: test_util: Print test stdout/stderr within test summaries" Remove concurrencytest patman: Move library functions into a library directory script: Add a script to build a PyPi package patman: Add support for building a u_boot_tools PyPi package patman: Avoid importing test_checkpatch before it is needed patman: Add support for building a patman PyPi package buildman: Move the main code into a function buildman: Hide the test options unless test code is available buildman: Fix use of a type as a variable buildman: Use importlib to find the help buildman: Add support for building a buildman PyPi package dtoc: Hide the test options unless test code is available dtoc: Move the main code into a function dtoc: Use pathlib to find the test directory dtoc: Add support for building a dtoc PyPi package binman: Move the main code into a function binman: Hide the 'test' command unless test code is available binman: Use importlib to find the help binman: Add support for building a binmanu PyPi package test: Add concurrencytest to the requirements doc: Add notes on how to install patman and binman CI: Add a check for building tools for PyPi
.azure-pipelines.yml | 10 + .gitlab-ci.yml | 6 + Makefile | 22 +- scripts/event_dump.py | 2 +- scripts/make_pip.sh | 117 ++++++ test/py/requirements.txt | 1 + test/run | 1 + tools/binman/binman.rst | 13 + tools/binman/bintool.py | 8 +- tools/binman/bintool_test.py | 8 +- tools/binman/btool/lz4.py | 2 +- tools/binman/btool/lzma_alone.py | 2 +- tools/binman/cbfs_util.py | 4 +- tools/binman/cbfs_util_test.py | 4 +- tools/binman/cmdline.py | 34 +- tools/binman/control.py | 12 +- tools/binman/elf.py | 6 +- tools/binman/elf_test.py | 8 +- tools/binman/entry.py | 6 +- tools/binman/entry_test.py | 2 +- tools/binman/etype/_testing.py | 2 +- tools/binman/etype/atf_fip.py | 2 +- tools/binman/etype/blob.py | 4 +- tools/binman/etype/blob_ext.py | 4 +- tools/binman/etype/blob_ext_list.py | 4 +- tools/binman/etype/fdtmap.py | 4 +- tools/binman/etype/files.py | 2 +- tools/binman/etype/fill.py | 2 +- tools/binman/etype/fit.py | 2 +- tools/binman/etype/fmap.py | 6 +- tools/binman/etype/gbb.py | 4 +- tools/binman/etype/intel_ifwi.py | 2 +- tools/binman/etype/mkimage.py | 2 +- tools/binman/etype/null.py | 2 +- tools/binman/etype/pre_load.py | 2 +- tools/binman/etype/section.py | 6 +- tools/binman/etype/text.py | 2 +- tools/binman/etype/u_boot_dtb_with_ucode.py | 2 +- tools/binman/etype/u_boot_elf.py | 2 +- tools/binman/etype/u_boot_env.py | 2 +- tools/binman/etype/u_boot_spl_bss_pad.py | 2 +- tools/binman/etype/u_boot_spl_expanded.py | 2 +- tools/binman/etype/u_boot_tpl_bss_pad.py | 2 +- tools/binman/etype/u_boot_tpl_expanded.py | 2 +- .../binman/etype/u_boot_tpl_with_ucode_ptr.py | 4 +- tools/binman/etype/u_boot_ucode.py | 2 +- tools/binman/etype/u_boot_vpl_bss_pad.py | 2 +- tools/binman/etype/u_boot_vpl_expanded.py | 2 +- tools/binman/etype/u_boot_with_ucode_ptr.py | 4 +- tools/binman/etype/vblock.py | 2 +- tools/binman/fdt_test.py | 2 +- tools/binman/fip_util.py | 4 +- tools/binman/fip_util_test.py | 4 +- tools/binman/fmap_util.py | 2 +- tools/binman/ftest.py | 17 +- tools/binman/image.py | 4 +- tools/binman/image_test.py | 2 +- tools/binman/main.py | 19 +- tools/binman/pyproject.toml | 29 ++ tools/binman/state.py | 4 +- tools/buildman/builder.py | 6 +- tools/buildman/builderthread.py | 2 +- tools/buildman/cfgutil.py | 2 +- tools/buildman/cmdline.py | 14 +- tools/buildman/control.py | 18 +- tools/buildman/func_test.py | 8 +- tools/buildman/main.py | 31 +- tools/buildman/pyproject.toml | 29 ++ tools/buildman/test.py | 8 +- tools/buildman/toolchain.py | 6 +- tools/concurrencytest/.gitignore | 1 - tools/concurrencytest/README.md | 74 ---- tools/concurrencytest/__init__.py | 0 tools/concurrencytest/concurrencytest.py | 221 ------------ tools/dtoc/README.rst | 15 + tools/dtoc/fdt.py | 2 +- tools/dtoc/fdt_util.py | 4 +- tools/dtoc/main.py | 110 +++--- tools/dtoc/pyproject.toml | 26 ++ tools/dtoc/test_dtoc.py | 10 +- tools/dtoc/test_fdt.py | 7 +- tools/dtoc/test_src_scan.py | 4 +- tools/patman/__init__.py | 7 +- tools/patman/__main__.py | 10 +- tools/patman/checkpatch.py | 4 +- tools/patman/control.py | 2 +- tools/patman/func_test.py | 6 +- tools/patman/get_maintainer.py | 2 +- tools/patman/gitutil.py | 4 +- tools/patman/patchstream.py | 2 +- tools/patman/patman.rst | 12 + tools/patman/pyproject.toml | 29 ++ tools/patman/series.py | 4 +- tools/patman/status.py | 4 +- tools/patman/test_settings.py | 2 +- tools/rmboard.py | 2 +- tools/u_boot_pylib/LICENSE | 339 ++++++++++++++++++ tools/u_boot_pylib/README.rst | 15 + tools/u_boot_pylib/__init__.py | 4 + tools/u_boot_pylib/__main__.py | 23 ++ tools/{patman => u_boot_pylib}/command.py | 2 +- .../cros_subprocess.py | 0 tools/u_boot_pylib/pyproject.toml | 22 ++ tools/{patman => u_boot_pylib}/terminal.py | 0 tools/{patman => u_boot_pylib}/test_util.py | 39 +- tools/{patman => u_boot_pylib}/tools.py | 4 +- tools/{patman => u_boot_pylib}/tout.py | 2 +- tools/u_boot_pylib/u_boot_pylib | 1 + 108 files changed, 1000 insertions(+), 576 deletions(-) create mode 100755 scripts/make_pip.sh create mode 100644 tools/binman/pyproject.toml create mode 100644 tools/buildman/pyproject.toml delete mode 100644 tools/concurrencytest/.gitignore delete mode 100644 tools/concurrencytest/README.md delete mode 100644 tools/concurrencytest/__init__.py delete mode 100644 tools/concurrencytest/concurrencytest.py create mode 100644 tools/dtoc/README.rst create mode 100644 tools/dtoc/pyproject.toml create mode 100644 tools/patman/pyproject.toml create mode 100644 tools/u_boot_pylib/LICENSE create mode 100644 tools/u_boot_pylib/README.rst create mode 100644 tools/u_boot_pylib/__init__.py create mode 100755 tools/u_boot_pylib/__main__.py rename tools/{patman => u_boot_pylib}/command.py (99%) rename tools/{patman => u_boot_pylib}/cros_subprocess.py (100%) create mode 100644 tools/u_boot_pylib/pyproject.toml rename tools/{patman => u_boot_pylib}/terminal.py (100%) rename tools/{patman => u_boot_pylib}/test_util.py (85%) rename tools/{patman => u_boot_pylib}/tools.py (99%) rename tools/{patman => u_boot_pylib}/tout.py (99%) create mode 120000 tools/u_boot_pylib/u_boot_pylib

This prints a message about the missing tee-os generated by the test. This is confusing, so suppress it.
Signed-off-by: Simon Glass sjg@chromium.org ---
(no changes since v1)
tools/binman/ftest.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py index 062f54adb0e..d469928b256 100644 --- a/tools/binman/ftest.py +++ b/tools/binman/ftest.py @@ -6353,10 +6353,11 @@ fdt fdtmap Extract the devicetree blob from the fdtmap 'tee-os-path': 'missing.bin', } test_subdir = os.path.join(self._indir, TEST_FDT_SUBDIR) - data = self._DoReadFileDtb( - '276_fit_firmware_loadables.dts', - entry_args=entry_args, - extra_indirs=[test_subdir])[0] + with test_util.capture_sys_output() as (stdout, stderr): + data = self._DoReadFileDtb( + '276_fit_firmware_loadables.dts', + entry_args=entry_args, + extra_indirs=[test_subdir])[0]
dtb = fdt.Fdt.FromData(data) dtb.Scan()

This prints a message about the missing tee-os generated by the test. This is confusing, so suppress it.
Signed-off-by: Simon Glass sjg@chromium.org ---
(no changes since v1)
tools/binman/ftest.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
Applied to u-boot-dm/next, thanks!

Unfortunately this adds a new feature to concurrencytest and it has not made it upstream to the project[1].
Drop it for now so we can use the upstream module. Once it is applied we can bring this functionality back.
[1] https://github.com/cgoldberg/concurrencytest
This reverts commit ebcaafcded40da8ae6cb4234c2ba9901c7bee644.
Signed-off-by: Simon Glass sjg@chromium.org ---
(no changes since v1)
tools/concurrencytest/concurrencytest.py | 83 +----------------------- tools/patman/test_util.py | 33 +--------- 2 files changed, 4 insertions(+), 112 deletions(-)
diff --git a/tools/concurrencytest/concurrencytest.py b/tools/concurrencytest/concurrencytest.py index 1c4f03f37e5..5e88b94f415 100644 --- a/tools/concurrencytest/concurrencytest.py +++ b/tools/concurrencytest/concurrencytest.py @@ -31,7 +31,6 @@ from subunit import ProtocolTestCase, TestProtocolClient from subunit.test_results import AutoTimingTestResultDecorator
from testtools import ConcurrentTestSuite, iterate_tests -from testtools.content import TracebackContent, text_content
_all__ = [ @@ -44,81 +43,11 @@ _all__ = [ CPU_COUNT = cpu_count()
-class BufferingTestProtocolClient(TestProtocolClient): - """A TestProtocolClient which can buffer the test outputs - - This class captures the stdout and stderr output streams of the - tests as it runs them, and includes the output texts in the subunit - stream as additional details. - - Args: - stream: A file-like object to write a subunit stream to - buffer (bool): True to capture test stdout/stderr outputs and - include them in the test details - """ - def __init__(self, stream, buffer=True): - super().__init__(stream) - self.buffer = buffer - - def _addOutcome(self, outcome, test, error=None, details=None, - error_permitted=True): - """Report a test outcome to the subunit stream - - The parent class uses this function as a common implementation - for various methods that report successes, errors, failures, etc. - - This version automatically upgrades the error tracebacks to the - new 'details' format by wrapping them in a Content object, so - that we can include the captured test output in the test result - details. - - Args: - outcome: A string describing the outcome - used as the - event name in the subunit stream. - test: The test case whose outcome is to be reported - error: Standard unittest positional argument form - an - exc_info tuple. - details: New Testing-in-python drafted API; a dict from - string to subunit.Content objects. - error_permitted: If True then one and only one of error or - details must be supplied. If False then error must not - be supplied and details is still optional. - """ - if details is None: - details = {} - - # Parent will raise an exception if error_permitted is False but - # error is not None. We want that exception in that case, so - # don't touch error when error_permitted is explicitly False. - if error_permitted and error is not None: - # Parent class prefers error over details - details['traceback'] = TracebackContent(error, test) - error_permitted = False - error = None - - if self.buffer: - stdout = sys.stdout.getvalue() - if stdout: - details['stdout'] = text_content(stdout) - - stderr = sys.stderr.getvalue() - if stderr: - details['stderr'] = text_content(stderr) - - return super()._addOutcome(outcome, test, error=error, - details=details, error_permitted=error_permitted) - - -def fork_for_tests(concurrency_num=CPU_COUNT, buffer=False): +def fork_for_tests(concurrency_num=CPU_COUNT): """Implementation of `make_tests` used to construct `ConcurrentTestSuite`.
:param concurrency_num: number of processes to use. """ - if buffer: - test_protocol_client_class = BufferingTestProtocolClient - else: - test_protocol_client_class = TestProtocolClient - def do_fork(suite): """Take suite and start up multiple runners by forking (Unix only).
@@ -147,7 +76,7 @@ def fork_for_tests(concurrency_num=CPU_COUNT, buffer=False): # child actually gets keystrokes for pdb etc). sys.stdin.close() subunit_result = AutoTimingTestResultDecorator( - test_protocol_client_class(stream) + TestProtocolClient(stream) ) process_suite.run(subunit_result) except: @@ -164,13 +93,7 @@ def fork_for_tests(concurrency_num=CPU_COUNT, buffer=False): else: os.close(c2pwrite) stream = os.fdopen(c2pread, 'rb') - # If we don't pass the second argument here, it defaults - # to sys.stdout.buffer down the line. But if we don't - # pass it *now*, it may be resolved after sys.stdout is - # replaced with a StringIO (to capture tests' outputs) - # which doesn't have a buffer attribute and can end up - # occasionally causing a 'broken-runner' error. - test = ProtocolTestCase(stream, sys.stdout.buffer) + test = ProtocolTestCase(stream) result.append(test) return result return do_fork diff --git a/tools/patman/test_util.py b/tools/patman/test_util.py index 0f6d1aa902d..4ee58f9fbb9 100644 --- a/tools/patman/test_util.py +++ b/tools/patman/test_util.py @@ -15,7 +15,6 @@ from patman import command
from io import StringIO
-buffer_outputs = True use_concurrent = True try: from concurrencytest.concurrencytest import ConcurrentTestSuite @@ -120,7 +119,6 @@ class FullTextTestResult(unittest.TextTestResult): 0: Print nothing 1: Print a dot per test 2: Print test names - 3: Print test names, and buffered outputs for failing tests """ def __init__(self, stream, descriptions, verbosity): self.verbosity = verbosity @@ -140,39 +138,12 @@ class FullTextTestResult(unittest.TextTestResult): self.printErrorList('XFAIL', self.expectedFailures) self.printErrorList('XPASS', unexpected_successes)
- def addError(self, test, err): - """Called when an error has occurred.""" - super().addError(test, err) - self._mirrorOutput &= self.verbosity >= 3 - - def addFailure(self, test, err): - """Called when a test has failed.""" - super().addFailure(test, err) - self._mirrorOutput &= self.verbosity >= 3 - - def addSubTest(self, test, subtest, err): - """Called at the end of a subtest.""" - super().addSubTest(test, subtest, err) - self._mirrorOutput &= self.verbosity >= 3 - - def addSuccess(self, test): - """Called when a test has completed successfully""" - super().addSuccess(test) - # Don't print stdout/stderr for successful tests - self._mirrorOutput = False - def addSkip(self, test, reason): """Called when a test is skipped.""" # Add empty line to keep spacing consistent with other results if not reason.endswith('\n'): reason += '\n' super().addSkip(test, reason) - self._mirrorOutput &= self.verbosity >= 3 - - def addExpectedFailure(self, test, err): - """Called when an expected failure/error occurred.""" - super().addExpectedFailure(test, err) - self._mirrorOutput &= self.verbosity >= 3
def run_test_suites(toolname, debug, verbosity, test_preserve_dirs, processes, @@ -208,14 +179,12 @@ def run_test_suites(toolname, debug, verbosity, test_preserve_dirs, processes, runner = unittest.TextTestRunner( stream=sys.stdout, verbosity=(1 if verbosity is None else verbosity), - buffer=False if test_name else buffer_outputs, resultclass=FullTextTestResult, )
if use_concurrent and processes != 1: suite = ConcurrentTestSuite(suite, - fork_for_tests(processes or multiprocessing.cpu_count(), - buffer=False if test_name else buffer_outputs)) + fork_for_tests(processes or multiprocessing.cpu_count()))
for module in class_and_module_list: if isinstance(module, str) and (not test_name or test_name == module):

Unfortunately this adds a new feature to concurrencytest and it has not made it upstream to the project[1].
Drop it for now so we can use the upstream module. Once it is applied we can bring this functionality back.
[1] https://github.com/cgoldberg/concurrencytest
This reverts commit ebcaafcded40da8ae6cb4234c2ba9901c7bee644.
Signed-off-by: Simon Glass sjg@chromium.org ---
(no changes since v1)
tools/concurrencytest/concurrencytest.py | 83 +----------------------- tools/patman/test_util.py | 33 +--------- 2 files changed, 4 insertions(+), 112 deletions(-)
Applied to u-boot-dm/next, thanks!

While our version is better, it is tricky to use it when we are trying to package things with pip. Drop it.
Somewhat reduced functionality is provided by the upstream version[1], along with a rather annoying message each time it is used[2] [3].
[1] pip install concurrencytest [2] https://github.com/cgoldberg/concurrencytest/issues/12 [3] https://github.com/cgoldberg/concurrencytest/pull/14
Signed-off-by: Simon Glass sjg@chromium.org ---
(no changes since v1)
tools/concurrencytest/.gitignore | 1 - tools/concurrencytest/README.md | 74 ------------ tools/concurrencytest/__init__.py | 0 tools/concurrencytest/concurrencytest.py | 144 ----------------------- tools/patman/test_util.py | 4 +- 5 files changed, 2 insertions(+), 221 deletions(-) delete mode 100644 tools/concurrencytest/.gitignore delete mode 100644 tools/concurrencytest/README.md delete mode 100644 tools/concurrencytest/__init__.py delete mode 100644 tools/concurrencytest/concurrencytest.py
diff --git a/tools/concurrencytest/.gitignore b/tools/concurrencytest/.gitignore deleted file mode 100644 index 0d20b6487c6..00000000000 --- a/tools/concurrencytest/.gitignore +++ /dev/null @@ -1 +0,0 @@ -*.pyc diff --git a/tools/concurrencytest/README.md b/tools/concurrencytest/README.md deleted file mode 100644 index 2d7fe75df53..00000000000 --- a/tools/concurrencytest/README.md +++ /dev/null @@ -1,74 +0,0 @@ -concurrencytest -=============== - - - -Python testtools extension for running unittest suites concurrently. - ----- - -Install from PyPI: -``` -pip install concurrencytest -``` - ----- - -Requires: - -* [testtools](https://pypi.python.org/pypi/testtools) : `pip install testtools` -* [python-subunit](https://pypi.python.org/pypi/python-subunit) : `pip install python-subunit` - ----- - -Example: - -```python -import time -import unittest - -from concurrencytest import ConcurrentTestSuite, fork_for_tests - - -class SampleTestCase(unittest.TestCase): - """Dummy tests that sleep for demo.""" - - def test_me_1(self): - time.sleep(0.5) - - def test_me_2(self): - time.sleep(0.5) - - def test_me_3(self): - time.sleep(0.5) - - def test_me_4(self): - time.sleep(0.5) - - -# Load tests from SampleTestCase defined above -suite = unittest.TestLoader().loadTestsFromTestCase(SampleTestCase) -runner = unittest.TextTestRunner() - -# Run tests sequentially -runner.run(suite) - -# Run same tests across 4 processes -suite = unittest.TestLoader().loadTestsFromTestCase(SampleTestCase) -concurrent_suite = ConcurrentTestSuite(suite, fork_for_tests(4)) -runner.run(concurrent_suite) -``` -Output: - -``` -.... ----------------------------------------------------------------------- -Ran 4 tests in 2.003s - -OK -.... ----------------------------------------------------------------------- -Ran 4 tests in 0.504s - -OK -``` diff --git a/tools/concurrencytest/__init__.py b/tools/concurrencytest/__init__.py deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/tools/concurrencytest/concurrencytest.py b/tools/concurrencytest/concurrencytest.py deleted file mode 100644 index 5e88b94f415..00000000000 --- a/tools/concurrencytest/concurrencytest.py +++ /dev/null @@ -1,144 +0,0 @@ -#!/usr/bin/env python -# SPDX-License-Identifier: GPL-2.0+ -# -# Modified by: Corey Goldberg, 2013 -# -# Original code from: -# Bazaar (bzrlib.tests.__init__.py, v2.6, copied Jun 01 2013) -# Copyright (C) 2005-2011 Canonical Ltd - -"""Python testtools extension for running unittest suites concurrently. - -The `testtools` project provides a ConcurrentTestSuite class, but does -not provide a `make_tests` implementation needed to use it. - -This allows you to parallelize a test run across a configurable number -of worker processes. While this can speed up CPU-bound test runs, it is -mainly useful for IO-bound tests that spend most of their time waiting for -data to arrive from someplace else and can benefit from cocncurrency. - -Unix only. -""" - -import os -import sys -import traceback -import unittest -from itertools import cycle -from multiprocessing import cpu_count - -from subunit import ProtocolTestCase, TestProtocolClient -from subunit.test_results import AutoTimingTestResultDecorator - -from testtools import ConcurrentTestSuite, iterate_tests - - -_all__ = [ - 'ConcurrentTestSuite', - 'fork_for_tests', - 'partition_tests', -] - - -CPU_COUNT = cpu_count() - - -def fork_for_tests(concurrency_num=CPU_COUNT): - """Implementation of `make_tests` used to construct `ConcurrentTestSuite`. - - :param concurrency_num: number of processes to use. - """ - def do_fork(suite): - """Take suite and start up multiple runners by forking (Unix only). - - :param suite: TestSuite object. - - :return: An iterable of TestCase-like objects which can each have - run(result) called on them to feed tests to result. - """ - result = [] - test_blocks = partition_tests(suite, concurrency_num) - # Clear the tests from the original suite so it doesn't keep them alive - suite._tests[:] = [] - for process_tests in test_blocks: - process_suite = unittest.TestSuite(process_tests) - # Also clear each split list so new suite has only reference - process_tests[:] = [] - c2pread, c2pwrite = os.pipe() - pid = os.fork() - if pid == 0: - try: - stream = os.fdopen(c2pwrite, 'wb') - os.close(c2pread) - # Leave stderr and stdout open so we can see test noise - # Close stdin so that the child goes away if it decides to - # read from stdin (otherwise its a roulette to see what - # child actually gets keystrokes for pdb etc). - sys.stdin.close() - subunit_result = AutoTimingTestResultDecorator( - TestProtocolClient(stream) - ) - process_suite.run(subunit_result) - except: - # Try and report traceback on stream, but exit with error - # even if stream couldn't be created or something else - # goes wrong. The traceback is formatted to a string and - # written in one go to avoid interleaving lines from - # multiple failing children. - try: - stream.write(traceback.format_exc()) - finally: - os._exit(1) - os._exit(0) - else: - os.close(c2pwrite) - stream = os.fdopen(c2pread, 'rb') - test = ProtocolTestCase(stream) - result.append(test) - return result - return do_fork - - -def partition_tests(suite, count): - """Partition suite into count lists of tests.""" - # This just assigns tests in a round-robin fashion. On one hand this - # splits up blocks of related tests that might run faster if they shared - # resources, but on the other it avoids assigning blocks of slow tests to - # just one partition. So the slowest partition shouldn't be much slower - # than the fastest. - partitions = [list() for _ in range(count)] - tests = iterate_tests(suite) - for partition, test in zip(cycle(partitions), tests): - partition.append(test) - return partitions - - -if __name__ == '__main__': - import time - - class SampleTestCase(unittest.TestCase): - """Dummy tests that sleep for demo.""" - - def test_me_1(self): - time.sleep(0.5) - - def test_me_2(self): - time.sleep(0.5) - - def test_me_3(self): - time.sleep(0.5) - - def test_me_4(self): - time.sleep(0.5) - - # Load tests from SampleTestCase defined above - suite = unittest.TestLoader().loadTestsFromTestCase(SampleTestCase) - runner = unittest.TextTestRunner() - - # Run tests sequentially - runner.run(suite) - - # Run same tests across 4 processes - suite = unittest.TestLoader().loadTestsFromTestCase(SampleTestCase) - concurrent_suite = ConcurrentTestSuite(suite, fork_for_tests(4)) - runner.run(concurrent_suite) diff --git a/tools/patman/test_util.py b/tools/patman/test_util.py index 4ee58f9fbb9..9e0811b61a2 100644 --- a/tools/patman/test_util.py +++ b/tools/patman/test_util.py @@ -17,8 +17,8 @@ from io import StringIO
use_concurrent = True try: - from concurrencytest.concurrencytest import ConcurrentTestSuite - from concurrencytest.concurrencytest import fork_for_tests + from concurrencytest import ConcurrentTestSuite + from concurrencytest import fork_for_tests except: use_concurrent = False

While our version is better, it is tricky to use it when we are trying to package things with pip. Drop it.
Somewhat reduced functionality is provided by the upstream version[1], along with a rather annoying message each time it is used[2] [3].
[1] pip install concurrencytest [2] https://github.com/cgoldberg/concurrencytest/issues/12 [3] https://github.com/cgoldberg/concurrencytest/pull/14
Signed-off-by: Simon Glass sjg@chromium.org ---
(no changes since v1)
tools/concurrencytest/.gitignore | 1 - tools/concurrencytest/README.md | 74 ------------ tools/concurrencytest/__init__.py | 0 tools/concurrencytest/concurrencytest.py | 144 ----------------------- tools/patman/test_util.py | 4 +- 5 files changed, 2 insertions(+), 221 deletions(-) delete mode 100644 tools/concurrencytest/.gitignore delete mode 100644 tools/concurrencytest/README.md delete mode 100644 tools/concurrencytest/__init__.py delete mode 100644 tools/concurrencytest/concurrencytest.py
Applied to u-boot-dm/next, thanks!

The patman directory has a number of modules which are used by other tools in U-Boot. This makes it hard to package the tools using pypi since the common files must be copied along with the tool that uses them.
To address this, move these files into a new u_boot_pylib library. This can be packaged separately and listed as a dependency of each tool.
Signed-off-by: Simon Glass sjg@chromium.org ---
(no changes since v1)
scripts/event_dump.py | 2 +- test/run | 1 + tools/binman/bintool.py | 8 +++---- tools/binman/bintool_test.py | 8 +++---- tools/binman/btool/lz4.py | 2 +- tools/binman/btool/lzma_alone.py | 2 +- tools/binman/cbfs_util.py | 4 ++-- tools/binman/cbfs_util_test.py | 4 ++-- tools/binman/control.py | 6 ++--- tools/binman/elf.py | 6 ++--- tools/binman/elf_test.py | 8 +++---- tools/binman/entry.py | 6 ++--- tools/binman/entry_test.py | 2 +- tools/binman/etype/_testing.py | 2 +- tools/binman/etype/atf_fip.py | 2 +- tools/binman/etype/blob.py | 4 ++-- tools/binman/etype/blob_ext.py | 4 ++-- tools/binman/etype/blob_ext_list.py | 4 ++-- tools/binman/etype/fdtmap.py | 4 ++-- tools/binman/etype/files.py | 2 +- tools/binman/etype/fill.py | 2 +- tools/binman/etype/fit.py | 2 +- tools/binman/etype/fmap.py | 6 ++--- tools/binman/etype/gbb.py | 4 ++-- tools/binman/etype/intel_ifwi.py | 2 +- tools/binman/etype/mkimage.py | 2 +- tools/binman/etype/null.py | 2 +- tools/binman/etype/pre_load.py | 2 +- tools/binman/etype/section.py | 6 ++--- tools/binman/etype/text.py | 2 +- tools/binman/etype/u_boot_dtb_with_ucode.py | 2 +- tools/binman/etype/u_boot_elf.py | 2 +- tools/binman/etype/u_boot_env.py | 2 +- tools/binman/etype/u_boot_spl_bss_pad.py | 2 +- tools/binman/etype/u_boot_spl_expanded.py | 2 +- tools/binman/etype/u_boot_tpl_bss_pad.py | 2 +- tools/binman/etype/u_boot_tpl_expanded.py | 2 +- .../binman/etype/u_boot_tpl_with_ucode_ptr.py | 4 ++-- tools/binman/etype/u_boot_ucode.py | 2 +- tools/binman/etype/u_boot_vpl_bss_pad.py | 2 +- tools/binman/etype/u_boot_vpl_expanded.py | 2 +- tools/binman/etype/u_boot_with_ucode_ptr.py | 4 ++-- tools/binman/etype/vblock.py | 2 +- tools/binman/fdt_test.py | 2 +- tools/binman/fip_util.py | 4 ++-- tools/binman/fip_util_test.py | 4 ++-- tools/binman/fmap_util.py | 2 +- tools/binman/ftest.py | 8 +++---- tools/binman/image.py | 4 ++-- tools/binman/image_test.py | 2 +- tools/binman/main.py | 7 +++--- tools/binman/state.py | 4 ++-- tools/buildman/builder.py | 6 ++--- tools/buildman/builderthread.py | 2 +- tools/buildman/cfgutil.py | 2 +- tools/buildman/control.py | 8 +++---- tools/buildman/func_test.py | 8 +++---- tools/buildman/main.py | 4 ++-- tools/buildman/test.py | 8 +++---- tools/buildman/toolchain.py | 6 ++--- tools/dtoc/fdt.py | 2 +- tools/dtoc/fdt_util.py | 4 ++-- tools/dtoc/main.py | 5 ++-- tools/dtoc/test_dtoc.py | 4 ++-- tools/dtoc/test_fdt.py | 7 +++--- tools/dtoc/test_src_scan.py | 4 ++-- tools/patman/__init__.py | 7 +++--- tools/patman/__main__.py | 8 +++---- tools/patman/checkpatch.py | 4 ++-- tools/patman/control.py | 2 +- tools/patman/func_test.py | 6 ++--- tools/patman/get_maintainer.py | 2 +- tools/patman/gitutil.py | 4 ++-- tools/patman/patchstream.py | 2 +- tools/patman/series.py | 4 ++-- tools/patman/status.py | 4 ++-- tools/patman/test_settings.py | 2 +- tools/rmboard.py | 2 +- tools/u_boot_pylib/__init__.py | 4 ++++ tools/u_boot_pylib/__main__.py | 23 +++++++++++++++++++ tools/{patman => u_boot_pylib}/command.py | 2 +- .../cros_subprocess.py | 0 tools/{patman => u_boot_pylib}/terminal.py | 0 tools/{patman => u_boot_pylib}/test_util.py | 2 +- tools/{patman => u_boot_pylib}/tools.py | 4 ++-- tools/{patman => u_boot_pylib}/tout.py | 2 +- tools/u_boot_pylib/u_boot_pylib | 1 + 87 files changed, 182 insertions(+), 151 deletions(-) create mode 100644 tools/u_boot_pylib/__init__.py create mode 100755 tools/u_boot_pylib/__main__.py rename tools/{patman => u_boot_pylib}/command.py (99%) rename tools/{patman => u_boot_pylib}/cros_subprocess.py (100%) rename tools/{patman => u_boot_pylib}/terminal.py (100%) rename tools/{patman => u_boot_pylib}/test_util.py (99%) rename tools/{patman => u_boot_pylib}/tools.py (99%) rename tools/{patman => u_boot_pylib}/tout.py (99%) create mode 120000 tools/u_boot_pylib/u_boot_pylib
diff --git a/scripts/event_dump.py b/scripts/event_dump.py index d87823f3749..0117457526e 100755 --- a/scripts/event_dump.py +++ b/scripts/event_dump.py @@ -15,7 +15,7 @@ src_path = os.path.dirname(our_path) sys.path.insert(1, os.path.join(our_path, '../tools'))
from binman import elf -from patman import tools +from u_boot_pylib import tools
# A typical symbol looks like this: # _u_boot_list_2_evspy_info_2_EVT_MISC_INIT_F_3_sandbox_misc_init_f diff --git a/test/run b/test/run index c4ab046ce8f..93b556f6cff 100755 --- a/test/run +++ b/test/run @@ -76,6 +76,7 @@ TOOLS_DIR=build-sandbox_spl/tools
run_test "binman" ./tools/binman/binman --toolpath ${TOOLS_DIR} test run_test "patman" ./tools/patman/patman test +run_test "u_boot_pylib" ./tools/u_boot_pylib/u_boot_pylib
run_test "buildman" ./tools/buildman/buildman -t ${skip} run_test "fdt" ./tools/dtoc/test_fdt -t diff --git a/tools/binman/bintool.py b/tools/binman/bintool.py index 8fda13ff012..745b62b5a20 100644 --- a/tools/binman/bintool.py +++ b/tools/binman/bintool.py @@ -18,10 +18,10 @@ import shutil import tempfile import urllib.error
-from patman import command -from patman import terminal -from patman import tools -from patman import tout +from u_boot_pylib import command +from u_boot_pylib import terminal +from u_boot_pylib import tools +from u_boot_pylib import tout
BINMAN_DIR = os.path.dirname(os.path.realpath(__file__))
diff --git a/tools/binman/bintool_test.py b/tools/binman/bintool_test.py index 7efb8391db2..87a6b11e676 100644 --- a/tools/binman/bintool_test.py +++ b/tools/binman/bintool_test.py @@ -16,10 +16,10 @@ import urllib.error from binman import bintool from binman.bintool import Bintool
-from patman import command -from patman import terminal -from patman import test_util -from patman import tools +from u_boot_pylib import command +from u_boot_pylib import terminal +from u_boot_pylib import test_util +from u_boot_pylib import tools
# pylint: disable=R0904 class TestBintool(unittest.TestCase): diff --git a/tools/binman/btool/lz4.py b/tools/binman/btool/lz4.py index dc9e37921a6..fd520d13a56 100644 --- a/tools/binman/btool/lz4.py +++ b/tools/binman/btool/lz4.py @@ -60,7 +60,7 @@ import re import tempfile
from binman import bintool -from patman import tools +from u_boot_pylib import tools
# pylint: disable=C0103 class Bintoollz4(bintool.Bintool): diff --git a/tools/binman/btool/lzma_alone.py b/tools/binman/btool/lzma_alone.py index 52a960fd2fa..1fda2f68c7b 100644 --- a/tools/binman/btool/lzma_alone.py +++ b/tools/binman/btool/lzma_alone.py @@ -37,7 +37,7 @@ import re import tempfile
from binman import bintool -from patman import tools +from u_boot_pylib import tools
# pylint: disable=C0103 class Bintoollzma_alone(bintool.Bintool): diff --git a/tools/binman/cbfs_util.py b/tools/binman/cbfs_util.py index 7bd3d897981..fc56b40b753 100644 --- a/tools/binman/cbfs_util.py +++ b/tools/binman/cbfs_util.py @@ -22,8 +22,8 @@ import sys
from binman import bintool from binman import elf -from patman import command -from patman import tools +from u_boot_pylib import command +from u_boot_pylib import tools
# Set to True to enable printing output while working DEBUG = False diff --git a/tools/binman/cbfs_util_test.py b/tools/binman/cbfs_util_test.py index e0f792fd344..ee951d10cf3 100755 --- a/tools/binman/cbfs_util_test.py +++ b/tools/binman/cbfs_util_test.py @@ -20,8 +20,8 @@ from binman import bintool from binman import cbfs_util from binman.cbfs_util import CbfsWriter from binman import elf -from patman import test_util -from patman import tools +from u_boot_pylib import test_util +from u_boot_pylib import tools
U_BOOT_DATA = b'1234' U_BOOT_DTB_DATA = b'udtb' diff --git a/tools/binman/control.py b/tools/binman/control.py index e64740094f6..3e27b72f881 100644 --- a/tools/binman/control.py +++ b/tools/binman/control.py @@ -12,14 +12,14 @@ import pkg_resources import re
import sys -from patman import tools
from binman import bintool from binman import cbfs_util -from patman import command from binman import elf from binman import entry -from patman import tout +from u_boot_pylib import command +from u_boot_pylib import tools +from u_boot_pylib import tout
# These are imported if needed since they import libfdt state = None diff --git a/tools/binman/elf.py b/tools/binman/elf.py index 3cc8a384495..5816284c32a 100644 --- a/tools/binman/elf.py +++ b/tools/binman/elf.py @@ -13,9 +13,9 @@ import shutil import struct import tempfile
-from patman import command -from patman import tools -from patman import tout +from u_boot_pylib import command +from u_boot_pylib import tools +from u_boot_pylib import tout
ELF_TOOLS = True try: diff --git a/tools/binman/elf_test.py b/tools/binman/elf_test.py index 8cb55ebb815..c98083961b5 100644 --- a/tools/binman/elf_test.py +++ b/tools/binman/elf_test.py @@ -12,10 +12,10 @@ import tempfile import unittest
from binman import elf -from patman import command -from patman import test_util -from patman import tools -from patman import tout +from u_boot_pylib import command +from u_boot_pylib import test_util +from u_boot_pylib import tools +from u_boot_pylib import tout
binman_dir = os.path.dirname(os.path.realpath(sys.argv[0]))
diff --git a/tools/binman/entry.py b/tools/binman/entry.py index 5eacc5fa6c4..13224523978 100644 --- a/tools/binman/entry.py +++ b/tools/binman/entry.py @@ -14,9 +14,9 @@ import time from binman import bintool from binman import elf from dtoc import fdt_util -from patman import tools -from patman.tools import to_hex, to_hex_size -from patman import tout +from u_boot_pylib import tools +from u_boot_pylib.tools import to_hex, to_hex_size +from u_boot_pylib import tout
modules = {}
diff --git a/tools/binman/entry_test.py b/tools/binman/entry_test.py index a6fbf62731f..ac6582cf86a 100644 --- a/tools/binman/entry_test.py +++ b/tools/binman/entry_test.py @@ -14,7 +14,7 @@ from binman import entry from binman.etype.blob import Entry_blob from dtoc import fdt from dtoc import fdt_util -from patman import tools +from u_boot_pylib import tools
class TestEntry(unittest.TestCase): def setUp(self): diff --git a/tools/binman/etype/_testing.py b/tools/binman/etype/_testing.py index 1c1efb21a44..e092d98ce15 100644 --- a/tools/binman/etype/_testing.py +++ b/tools/binman/etype/_testing.py @@ -9,7 +9,7 @@ from collections import OrderedDict
from binman.entry import Entry, EntryArg from dtoc import fdt_util -from patman import tools +from u_boot_pylib import tools
class Entry__testing(Entry): diff --git a/tools/binman/etype/atf_fip.py b/tools/binman/etype/atf_fip.py index 6ecd95b71f9..d5b862040b4 100644 --- a/tools/binman/etype/atf_fip.py +++ b/tools/binman/etype/atf_fip.py @@ -11,7 +11,7 @@ from binman.entry import Entry from binman.etype.section import Entry_section from binman.fip_util import FIP_TYPES, FipReader, FipWriter, UUID_LEN from dtoc import fdt_util -from patman import tools +from u_boot_pylib import tools
class Entry_atf_fip(Entry_section): """ARM Trusted Firmware's Firmware Image Package (FIP) diff --git a/tools/binman/etype/blob.py b/tools/binman/etype/blob.py index c7ddcedffb8..f9c4e33b110 100644 --- a/tools/binman/etype/blob.py +++ b/tools/binman/etype/blob.py @@ -8,8 +8,8 @@ from binman.entry import Entry from binman import state from dtoc import fdt_util -from patman import tools -from patman import tout +from u_boot_pylib import tools +from u_boot_pylib import tout
class Entry_blob(Entry): """Arbitrary binary blob diff --git a/tools/binman/etype/blob_ext.py b/tools/binman/etype/blob_ext.py index fba6271de2b..9eb762b0a23 100644 --- a/tools/binman/etype/blob_ext.py +++ b/tools/binman/etype/blob_ext.py @@ -9,8 +9,8 @@ import os
from binman.etype.blob import Entry_blob from dtoc import fdt_util -from patman import tools -from patman import tout +from u_boot_pylib import tools +from u_boot_pylib import tout
class Entry_blob_ext(Entry_blob): """Externally built binary blob diff --git a/tools/binman/etype/blob_ext_list.py b/tools/binman/etype/blob_ext_list.py index f00202e9ebc..1bfcf6733a7 100644 --- a/tools/binman/etype/blob_ext_list.py +++ b/tools/binman/etype/blob_ext_list.py @@ -9,8 +9,8 @@ import os
from binman.etype.blob import Entry_blob from dtoc import fdt_util -from patman import tools -from patman import tout +from u_boot_pylib import tools +from u_boot_pylib import tout
class Entry_blob_ext_list(Entry_blob): """List of externally built binary blobs diff --git a/tools/binman/etype/fdtmap.py b/tools/binman/etype/fdtmap.py index 33c9d039a91..f1f6217940f 100644 --- a/tools/binman/etype/fdtmap.py +++ b/tools/binman/etype/fdtmap.py @@ -9,8 +9,8 @@ image. """
from binman.entry import Entry -from patman import tools -from patman import tout +from u_boot_pylib import tools +from u_boot_pylib import tout
FDTMAP_MAGIC = b'_FDTMAP_' FDTMAP_HDR_LEN = 16 diff --git a/tools/binman/etype/files.py b/tools/binman/etype/files.py index 2081bc727b9..c8757eafab1 100644 --- a/tools/binman/etype/files.py +++ b/tools/binman/etype/files.py @@ -11,7 +11,7 @@ import os
from binman.etype.section import Entry_section from dtoc import fdt_util -from patman import tools +from u_boot_pylib import tools
# This is imported if needed state = None diff --git a/tools/binman/etype/fill.py b/tools/binman/etype/fill.py index c91d0152a8a..7c93d4e2689 100644 --- a/tools/binman/etype/fill.py +++ b/tools/binman/etype/fill.py @@ -5,7 +5,7 @@
from binman.entry import Entry from dtoc import fdt_util -from patman import tools +from u_boot_pylib import tools
class Entry_fill(Entry): """An entry which is filled to a particular byte value diff --git a/tools/binman/etype/fit.py b/tools/binman/etype/fit.py index cd2943533ce..9d34aabd19a 100644 --- a/tools/binman/etype/fit.py +++ b/tools/binman/etype/fit.py @@ -12,7 +12,7 @@ from binman.etype.section import Entry_section from binman import elf from dtoc import fdt_util from dtoc.fdt import Fdt -from patman import tools +from u_boot_pylib import tools
# Supported operations, with the fit,operation property OP_GEN_FDT_NODES, OP_SPLIT_ELF = range(2) diff --git a/tools/binman/etype/fmap.py b/tools/binman/etype/fmap.py index 0c576202a48..dacdafd8f6f 100644 --- a/tools/binman/etype/fmap.py +++ b/tools/binman/etype/fmap.py @@ -7,9 +7,9 @@
from binman.entry import Entry from binman import fmap_util -from patman import tools -from patman.tools import to_hex_size -from patman import tout +from u_boot_pylib import tools +from u_boot_pylib.tools import to_hex_size +from u_boot_pylib import tout
class Entry_fmap(Entry): diff --git a/tools/binman/etype/gbb.py b/tools/binman/etype/gbb.py index ba2a362bb59..cca18af6e2f 100644 --- a/tools/binman/etype/gbb.py +++ b/tools/binman/etype/gbb.py @@ -8,11 +8,11 @@
from collections import OrderedDict
-from patman import command +from u_boot_pylib import command from binman.entry import Entry, EntryArg
from dtoc import fdt_util -from patman import tools +from u_boot_pylib import tools
# Build GBB flags. # (src/platform/vboot_reference/firmware/include/gbb_header.h) diff --git a/tools/binman/etype/intel_ifwi.py b/tools/binman/etype/intel_ifwi.py index 04fad401eee..6513b97c3e5 100644 --- a/tools/binman/etype/intel_ifwi.py +++ b/tools/binman/etype/intel_ifwi.py @@ -10,7 +10,7 @@ from collections import OrderedDict from binman.entry import Entry from binman.etype.blob_ext import Entry_blob_ext from dtoc import fdt_util -from patman import tools +from u_boot_pylib import tools
class Entry_intel_ifwi(Entry_blob_ext): """Intel Integrated Firmware Image (IFWI) file diff --git a/tools/binman/etype/mkimage.py b/tools/binman/etype/mkimage.py index cb264c3cad0..27a0c4bd7c6 100644 --- a/tools/binman/etype/mkimage.py +++ b/tools/binman/etype/mkimage.py @@ -9,7 +9,7 @@ from collections import OrderedDict
from binman.entry import Entry from dtoc import fdt_util -from patman import tools +from u_boot_pylib import tools
class Entry_mkimage(Entry): """Binary produced by mkimage diff --git a/tools/binman/etype/null.py b/tools/binman/etype/null.py index c10d4824472..263fb5244df 100644 --- a/tools/binman/etype/null.py +++ b/tools/binman/etype/null.py @@ -5,7 +5,7 @@
from binman.entry import Entry from dtoc import fdt_util -from patman import tools +from u_boot_pylib import tools
class Entry_null(Entry): """An entry which has no contents of its own diff --git a/tools/binman/etype/pre_load.py b/tools/binman/etype/pre_load.py index b6222811592..bd3545bffc0 100644 --- a/tools/binman/etype/pre_load.py +++ b/tools/binman/etype/pre_load.py @@ -8,7 +8,7 @@ import os import struct from dtoc import fdt_util -from patman import tools +from u_boot_pylib import tools
from binman.entry import Entry from binman.etype.collection import Entry_collection diff --git a/tools/binman/etype/section.py b/tools/binman/etype/section.py index 57b91ff726c..1f0bbd7f2ce 100644 --- a/tools/binman/etype/section.py +++ b/tools/binman/etype/section.py @@ -16,9 +16,9 @@ import sys from binman.entry import Entry from binman import state from dtoc import fdt_util -from patman import tools -from patman import tout -from patman.tools import to_hex_size +from u_boot_pylib import tools +from u_boot_pylib import tout +from u_boot_pylib.tools import to_hex_size
class Entry_section(Entry): diff --git a/tools/binman/etype/text.py b/tools/binman/etype/text.py index c55e0233b1e..e4deb4abacc 100644 --- a/tools/binman/etype/text.py +++ b/tools/binman/etype/text.py @@ -7,7 +7,7 @@ from collections import OrderedDict
from binman.entry import Entry, EntryArg from dtoc import fdt_util -from patman import tools +from u_boot_pylib import tools
class Entry_text(Entry): diff --git a/tools/binman/etype/u_boot_dtb_with_ucode.py b/tools/binman/etype/u_boot_dtb_with_ucode.py index 047d310cdf4..f7225cecc16 100644 --- a/tools/binman/etype/u_boot_dtb_with_ucode.py +++ b/tools/binman/etype/u_boot_dtb_with_ucode.py @@ -7,7 +7,7 @@
from binman.entry import Entry from binman.etype.blob_dtb import Entry_blob_dtb -from patman import tools +from u_boot_pylib import tools
# This is imported if needed state = None diff --git a/tools/binman/etype/u_boot_elf.py b/tools/binman/etype/u_boot_elf.py index 3ec774f38ad..f4d86aa176a 100644 --- a/tools/binman/etype/u_boot_elf.py +++ b/tools/binman/etype/u_boot_elf.py @@ -9,7 +9,7 @@ from binman.entry import Entry from binman.etype.blob import Entry_blob
from dtoc import fdt_util -from patman import tools +from u_boot_pylib import tools
class Entry_u_boot_elf(Entry_blob): """U-Boot ELF image diff --git a/tools/binman/etype/u_boot_env.py b/tools/binman/etype/u_boot_env.py index c38340b256e..c027e93d42c 100644 --- a/tools/binman/etype/u_boot_env.py +++ b/tools/binman/etype/u_boot_env.py @@ -8,7 +8,7 @@ import zlib
from binman.etype.blob import Entry_blob from dtoc import fdt_util -from patman import tools +from u_boot_pylib import tools
class Entry_u_boot_env(Entry_blob): """An entry which contains a U-Boot environment diff --git a/tools/binman/etype/u_boot_spl_bss_pad.py b/tools/binman/etype/u_boot_spl_bss_pad.py index 680d1983056..1ffeb3911fd 100644 --- a/tools/binman/etype/u_boot_spl_bss_pad.py +++ b/tools/binman/etype/u_boot_spl_bss_pad.py @@ -10,7 +10,7 @@ from binman import elf from binman.entry import Entry from binman.etype.blob import Entry_blob -from patman import tools +from u_boot_pylib import tools
class Entry_u_boot_spl_bss_pad(Entry_blob): """U-Boot SPL binary padded with a BSS region diff --git a/tools/binman/etype/u_boot_spl_expanded.py b/tools/binman/etype/u_boot_spl_expanded.py index 319f6708fe6..fcd0dd19ac4 100644 --- a/tools/binman/etype/u_boot_spl_expanded.py +++ b/tools/binman/etype/u_boot_spl_expanded.py @@ -5,7 +5,7 @@ # Entry-type module for expanded U-Boot SPL binary #
-from patman import tout +from u_boot_pylib import tout
from binman import state from binman.etype.blob_phase import Entry_blob_phase diff --git a/tools/binman/etype/u_boot_tpl_bss_pad.py b/tools/binman/etype/u_boot_tpl_bss_pad.py index 47f4b23f357..29c6a954129 100644 --- a/tools/binman/etype/u_boot_tpl_bss_pad.py +++ b/tools/binman/etype/u_boot_tpl_bss_pad.py @@ -10,7 +10,7 @@ from binman import elf from binman.entry import Entry from binman.etype.blob import Entry_blob -from patman import tools +from u_boot_pylib import tools
class Entry_u_boot_tpl_bss_pad(Entry_blob): """U-Boot TPL binary padded with a BSS region diff --git a/tools/binman/etype/u_boot_tpl_expanded.py b/tools/binman/etype/u_boot_tpl_expanded.py index 55fde3c8e66..58db4f37556 100644 --- a/tools/binman/etype/u_boot_tpl_expanded.py +++ b/tools/binman/etype/u_boot_tpl_expanded.py @@ -5,7 +5,7 @@ # Entry-type module for expanded U-Boot TPL binary #
-from patman import tout +from u_boot_pylib import tout
from binman import state from binman.etype.blob_phase import Entry_blob_phase diff --git a/tools/binman/etype/u_boot_tpl_with_ucode_ptr.py b/tools/binman/etype/u_boot_tpl_with_ucode_ptr.py index c7f3f9dedb5..86f9578b714 100644 --- a/tools/binman/etype/u_boot_tpl_with_ucode_ptr.py +++ b/tools/binman/etype/u_boot_tpl_with_ucode_ptr.py @@ -7,11 +7,11 @@
import struct
-from patman import command from binman.entry import Entry from binman.etype.blob import Entry_blob from binman.etype.u_boot_with_ucode_ptr import Entry_u_boot_with_ucode_ptr -from patman import tools +from u_boot_pylib import command +from u_boot_pylib import tools
class Entry_u_boot_tpl_with_ucode_ptr(Entry_u_boot_with_ucode_ptr): """U-Boot TPL with embedded microcode pointer diff --git a/tools/binman/etype/u_boot_ucode.py b/tools/binman/etype/u_boot_ucode.py index 6945411cf90..97ed7d7eb14 100644 --- a/tools/binman/etype/u_boot_ucode.py +++ b/tools/binman/etype/u_boot_ucode.py @@ -7,7 +7,7 @@
from binman.entry import Entry from binman.etype.blob import Entry_blob -from patman import tools +from u_boot_pylib import tools
class Entry_u_boot_ucode(Entry_blob): """U-Boot microcode block diff --git a/tools/binman/etype/u_boot_vpl_bss_pad.py b/tools/binman/etype/u_boot_vpl_bss_pad.py index b2ce2a31352..bba38ccf9e9 100644 --- a/tools/binman/etype/u_boot_vpl_bss_pad.py +++ b/tools/binman/etype/u_boot_vpl_bss_pad.py @@ -10,7 +10,7 @@ from binman import elf from binman.entry import Entry from binman.etype.blob import Entry_blob -from patman import tools +from u_boot_pylib import tools
class Entry_u_boot_vpl_bss_pad(Entry_blob): """U-Boot VPL binary padded with a BSS region diff --git a/tools/binman/etype/u_boot_vpl_expanded.py b/tools/binman/etype/u_boot_vpl_expanded.py index 92c64f0a65e..deff5a3f8c2 100644 --- a/tools/binman/etype/u_boot_vpl_expanded.py +++ b/tools/binman/etype/u_boot_vpl_expanded.py @@ -5,7 +5,7 @@ # Entry-type module for expanded U-Boot VPL binary #
-from patman import tout +from u_boot_pylib import tout
from binman import state from binman.etype.blob_phase import Entry_blob_phase diff --git a/tools/binman/etype/u_boot_with_ucode_ptr.py b/tools/binman/etype/u_boot_with_ucode_ptr.py index e275698cebe..41731fd0e13 100644 --- a/tools/binman/etype/u_boot_with_ucode_ptr.py +++ b/tools/binman/etype/u_boot_with_ucode_ptr.py @@ -11,8 +11,8 @@ from binman import elf from binman.entry import Entry from binman.etype.blob import Entry_blob from dtoc import fdt_util -from patman import tools -from patman import command +from u_boot_pylib import tools +from u_boot_pylib import command
class Entry_u_boot_with_ucode_ptr(Entry_blob): """U-Boot with embedded microcode pointer diff --git a/tools/binman/etype/vblock.py b/tools/binman/etype/vblock.py index 04cb7228aa0..4adb9a4e9bf 100644 --- a/tools/binman/etype/vblock.py +++ b/tools/binman/etype/vblock.py @@ -13,7 +13,7 @@ from binman.entry import EntryArg from binman.etype.collection import Entry_collection
from dtoc import fdt_util -from patman import tools +from u_boot_pylib import tools
class Entry_vblock(Entry_collection): """An entry which contains a Chromium OS verified boot block diff --git a/tools/binman/fdt_test.py b/tools/binman/fdt_test.py index 94347b1a1e2..7ef87295463 100644 --- a/tools/binman/fdt_test.py +++ b/tools/binman/fdt_test.py @@ -12,7 +12,7 @@ import unittest from dtoc import fdt from dtoc import fdt_util from dtoc.fdt import FdtScan -from patman import tools +from u_boot_pylib import tools
class TestFdt(unittest.TestCase): @classmethod diff --git a/tools/binman/fip_util.py b/tools/binman/fip_util.py index 95eee32bc00..b5caab2d37a 100755 --- a/tools/binman/fip_util.py +++ b/tools/binman/fip_util.py @@ -37,8 +37,8 @@ OUR_PATH = os.path.dirname(OUR_FILE) sys.path.insert(2, os.path.join(OUR_PATH, '..'))
# pylint: disable=C0413 -from patman import command -from patman import tools +from u_boot_pylib import command +from u_boot_pylib import tools
# The TOC header, at the start of the FIP HEADER_FORMAT = '<IIQ' diff --git a/tools/binman/fip_util_test.py b/tools/binman/fip_util_test.py index cf6d0002ec6..56aa56f4643 100755 --- a/tools/binman/fip_util_test.py +++ b/tools/binman/fip_util_test.py @@ -20,10 +20,10 @@ OUR_PATH = os.path.dirname(os.path.realpath(__file__)) sys.path.insert(2, os.path.join(OUR_PATH, '..'))
# pylint: disable=C0413 -from patman import test_util -from patman import tools from binman import bintool from binman import fip_util +from u_boot_pylib import test_util +from u_boot_pylib import tools
FIPTOOL = bintool.Bintool.create('fiptool') HAVE_FIPTOOL = FIPTOOL.is_present() diff --git a/tools/binman/fmap_util.py b/tools/binman/fmap_util.py index 1ce63d1a832..ea8d6a45008 100644 --- a/tools/binman/fmap_util.py +++ b/tools/binman/fmap_util.py @@ -10,7 +10,7 @@ import collections import struct import sys
-from patman import tools +from u_boot_pylib import tools
# constants imported from lib/fmap.h FMAP_SIGNATURE = b'__FMAP__' diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py index d469928b256..3cb17b6dec8 100644 --- a/tools/binman/ftest.py +++ b/tools/binman/ftest.py @@ -34,10 +34,10 @@ from dtoc import fdt_util from binman.etype import fdtmap from binman.etype import image_header from binman.image import Image -from patman import command -from patman import test_util -from patman import tools -from patman import tout +from u_boot_pylib import command +from u_boot_pylib import test_util +from u_boot_pylib import tools +from u_boot_pylib import tout
# Contents of test files, corresponding to different entry types U_BOOT_DATA = b'1234' diff --git a/tools/binman/image.py b/tools/binman/image.py index 941596320c1..8ebf71d61a8 100644 --- a/tools/binman/image.py +++ b/tools/binman/image.py @@ -18,8 +18,8 @@ from binman.etype import image_header from binman.etype import section from dtoc import fdt from dtoc import fdt_util -from patman import tools -from patman import tout +from u_boot_pylib import tools +from u_boot_pylib import tout
class Image(section.Entry_section): """A Image, representing an output from binman diff --git a/tools/binman/image_test.py b/tools/binman/image_test.py index e351fa84ab3..bd51c1e55d1 100644 --- a/tools/binman/image_test.py +++ b/tools/binman/image_test.py @@ -7,7 +7,7 @@ import unittest
from binman.image import Image -from patman.test_util import capture_sys_output +from u_boot_pylib.test_util import capture_sys_output
class TestImage(unittest.TestCase): def testInvalidFormat(self): diff --git a/tools/binman/main.py b/tools/binman/main.py index 14432a8d0dc..eef17b7b55f 100755 --- a/tools/binman/main.py +++ b/tools/binman/main.py @@ -34,7 +34,7 @@ sys.pycache_prefix = os.path.relpath(our_path, srctree) sys.path.insert(2, our1_path)
from binman import bintool -from patman import test_util +from u_boot_pylib import test_util
# Bring in the libfdt module sys.path.insert(2, 'scripts/dtc/pylibfdt') @@ -44,7 +44,7 @@ sys.path.insert(2, os.path.join(srctree, 'build-sandbox_spl/scripts/dtc/pylibfdt
from binman import cmdline from binman import control -from patman import test_util +from u_boot_pylib import test_util
def RunTests(debug, verbosity, processes, test_preserve_dirs, args, toolpath): """Run the functional tests and any embedded doctests @@ -95,7 +95,8 @@ def RunTestCoverage(toolpath): for path in toolpath: extra_args += ' --toolpath %s' % path test_util.run_test_coverage('tools/binman/binman', None, - ['*test*', '*main.py', 'tools/patman/*', 'tools/dtoc/*'], + ['*test*', '*main.py', 'tools/patman/*', 'tools/dtoc/*', + 'tools/u_boot_pylib/*'], args.build_dir, all_set, extra_args or None)
def RunBinman(args): diff --git a/tools/binman/state.py b/tools/binman/state.py index 56e5bf8bc10..87748d4ea36 100644 --- a/tools/binman/state.py +++ b/tools/binman/state.py @@ -13,8 +13,8 @@ import threading
from dtoc import fdt import os -from patman import tools -from patman import tout +from u_boot_pylib import tools +from u_boot_pylib import tout
OUR_PATH = os.path.dirname(os.path.realpath(__file__))
diff --git a/tools/buildman/builder.py b/tools/buildman/builder.py index c2a69027f88..cbfffe191eb 100644 --- a/tools/buildman/builder.py +++ b/tools/buildman/builder.py @@ -19,10 +19,10 @@ import time
from buildman import builderthread from buildman import toolchain -from patman import command from patman import gitutil -from patman import terminal -from patman.terminal import tprint +from u_boot_pylib import command +from u_boot_pylib import terminal +from u_boot_pylib.terminal import tprint
# This indicates an new int or hex Kconfig property with no default # It hangs the build since the 'conf' tool cannot proceed without valid input. diff --git a/tools/buildman/builderthread.py b/tools/buildman/builderthread.py index 680efae02d7..b8274addb4a 100644 --- a/tools/buildman/builderthread.py +++ b/tools/buildman/builderthread.py @@ -10,8 +10,8 @@ import sys import threading
from buildman import cfgutil -from patman import command from patman import gitutil +from u_boot_pylib import command
RETURN_CODE_RETRY = -1 BASE_ELF_FILENAMES = ['u-boot', 'spl/u-boot-spl', 'tpl/u-boot-tpl'] diff --git a/tools/buildman/cfgutil.py b/tools/buildman/cfgutil.py index ab74a8ef062..a340e01cb6b 100644 --- a/tools/buildman/cfgutil.py +++ b/tools/buildman/cfgutil.py @@ -7,7 +7,7 @@
import re
-from patman import tools +from u_boot_pylib import tools
RE_LINE = re.compile(r'(# )?CONFIG_([A-Z0-9_]+)(=(.*)| is not set)') RE_CFG = re.compile(r'(~?)(CONFIG_)?([A-Z0-9_]+)(=.*)?') diff --git a/tools/buildman/control.py b/tools/buildman/control.py index 87e7d0e2012..76e4e2709ac 100644 --- a/tools/buildman/control.py +++ b/tools/buildman/control.py @@ -13,12 +13,12 @@ from buildman import bsettings from buildman import cfgutil from buildman import toolchain from buildman.builder import Builder -from patman import command from patman import gitutil from patman import patchstream -from patman import terminal -from patman import tools -from patman.terminal import tprint +from u_boot_pylib import command +from u_boot_pylib import terminal +from u_boot_pylib import tools +from u_boot_pylib.terminal import tprint
def GetPlural(count): """Returns a plural 's' if count is not 1""" diff --git a/tools/buildman/func_test.py b/tools/buildman/func_test.py index 559e4edf74b..3885b9f083b 100644 --- a/tools/buildman/func_test.py +++ b/tools/buildman/func_test.py @@ -14,11 +14,11 @@ from buildman import bsettings from buildman import cmdline from buildman import control from buildman import toolchain -from patman import command from patman import gitutil -from patman import terminal -from patman import test_util -from patman import tools +from u_boot_pylib import command +from u_boot_pylib import terminal +from u_boot_pylib import test_util +from u_boot_pylib import tools
settings_data = ''' # Buildman settings file diff --git a/tools/buildman/main.py b/tools/buildman/main.py index 67c560c48d3..6076ba5d63d 100755 --- a/tools/buildman/main.py +++ b/tools/buildman/main.py @@ -25,8 +25,8 @@ from buildman import control from buildman import toolchain from patman import patchstream from patman import gitutil -from patman import terminal -from patman import test_util +from u_boot_pylib import terminal +from u_boot_pylib import test_util
def RunTests(skip_net_tests, verboose, args): from buildman import func_test diff --git a/tools/buildman/test.py b/tools/buildman/test.py index daf5467503e..9fa6445b798 100644 --- a/tools/buildman/test.py +++ b/tools/buildman/test.py @@ -17,10 +17,10 @@ from buildman import cfgutil from buildman import control from buildman import toolchain from patman import commit -from patman import command -from patman import terminal -from patman import test_util -from patman import tools +from u_boot_pylib import command +from u_boot_pylib import terminal +from u_boot_pylib import test_util +from u_boot_pylib import tools
use_network = True
diff --git a/tools/buildman/toolchain.py b/tools/buildman/toolchain.py index ea1ad1bcb83..688f2e26872 100644 --- a/tools/buildman/toolchain.py +++ b/tools/buildman/toolchain.py @@ -11,9 +11,9 @@ import tempfile import urllib.request, urllib.error, urllib.parse
from buildman import bsettings -from patman import command -from patman import terminal -from patman import tools +from u_boot_pylib import command +from u_boot_pylib import terminal +from u_boot_pylib import tools
(PRIORITY_FULL_PREFIX, PRIORITY_PREFIX_GCC, PRIORITY_PREFIX_GCC_PATH, PRIORITY_CALC) = list(range(4)) diff --git a/tools/dtoc/fdt.py b/tools/dtoc/fdt.py index d933972918b..a8e05349a72 100644 --- a/tools/dtoc/fdt.py +++ b/tools/dtoc/fdt.py @@ -12,7 +12,7 @@ import sys from dtoc import fdt_util import libfdt from libfdt import QUIET_NOTFOUND -from patman import tools +from u_boot_pylib import tools
# This deals with a device tree, presenting it as an assortment of Node and # Prop objects, representing nodes and properties, respectively. This file diff --git a/tools/dtoc/fdt_util.py b/tools/dtoc/fdt_util.py index f34316632a7..f1f70568cfe 100644 --- a/tools/dtoc/fdt_util.py +++ b/tools/dtoc/fdt_util.py @@ -13,8 +13,8 @@ import struct import sys import tempfile
-from patman import command -from patman import tools +from u_boot_pylib import command +from u_boot_pylib import tools
def fdt32_to_cpu(val): """Convert a device tree cell to an integer diff --git a/tools/dtoc/main.py b/tools/dtoc/main.py index 5508759d4d5..fc9207d1b63 100755 --- a/tools/dtoc/main.py +++ b/tools/dtoc/main.py @@ -35,7 +35,7 @@ sys.path.insert(0, os.path.join(our_path, '../../build-sandbox_spl/scripts/dtc/pylibfdt'))
from dtoc import dtb_platdata -from patman import test_util +from u_boot_pylib import test_util
def run_tests(processes, args): """Run all the test we have for dtoc @@ -65,7 +65,8 @@ def RunTestCoverage(): """Run the tests and check that we get 100% coverage""" sys.argv = [sys.argv[0]] test_util.run_test_coverage('tools/dtoc/dtoc', '/main.py', - ['tools/patman/*.py', '*/fdt*', '*test*'], args.build_dir) + ['tools/patman/*.py', 'tools/u_boot_pylib/*','*/fdt*', '*test*'], + args.build_dir)
if __name__ != '__main__': diff --git a/tools/dtoc/test_dtoc.py b/tools/dtoc/test_dtoc.py index c62fcbac83f..0f544f9f54a 100755 --- a/tools/dtoc/test_dtoc.py +++ b/tools/dtoc/test_dtoc.py @@ -25,8 +25,8 @@ from dtoc.dtb_platdata import get_value from dtoc.dtb_platdata import tab_to from dtoc.src_scan import conv_name_to_c from dtoc.src_scan import get_compat_name -from patman import test_util -from patman import tools +from u_boot_pylib import test_util +from u_boot_pylib import tools
OUR_PATH = os.path.dirname(os.path.realpath(__file__))
diff --git a/tools/dtoc/test_fdt.py b/tools/dtoc/test_fdt.py index dffa86fc190..32fa69cbb01 100755 --- a/tools/dtoc/test_fdt.py +++ b/tools/dtoc/test_fdt.py @@ -30,8 +30,8 @@ from dtoc import fdt_util from dtoc.fdt_util import fdt32_to_cpu, fdt64_to_cpu from dtoc.fdt import Type, BytesToValue import libfdt -from patman import test_util -from patman import tools +from u_boot_pylib import test_util +from u_boot_pylib import tools
#pylint: disable=protected-access
@@ -814,7 +814,8 @@ def run_test_coverage(build_dir): build_dir (str): Directory containing the build output """ test_util.run_test_coverage('tools/dtoc/test_fdt.py', None, - ['tools/patman/*.py', '*test_fdt.py'], build_dir) + ['tools/patman/*.py', 'tools/u_boot_pylib/*', '*test_fdt.py'], + build_dir)
def run_tests(names, processes): diff --git a/tools/dtoc/test_src_scan.py b/tools/dtoc/test_src_scan.py index f93cd7f5a3a..64b740841ca 100644 --- a/tools/dtoc/test_src_scan.py +++ b/tools/dtoc/test_src_scan.py @@ -15,8 +15,8 @@ import unittest from unittest import mock
from dtoc import src_scan -from patman import test_util -from patman import tools +from u_boot_pylib import test_util +from u_boot_pylib import tools
OUR_PATH = os.path.dirname(os.path.realpath(__file__))
diff --git a/tools/patman/__init__.py b/tools/patman/__init__.py index 1b98ec7feee..08eeffdf6d2 100644 --- a/tools/patman/__init__.py +++ b/tools/patman/__init__.py @@ -1,6 +1,5 @@ # SPDX-License-Identifier: GPL-2.0+
-__all__ = ['checkpatch', 'command', 'commit', 'control', 'cros_subprocess', - 'func_test', 'get_maintainer', 'gitutil', '__main__', 'patchstream', - 'project', 'series', 'setup', 'settings', 'terminal', - 'test_checkpatch', 'test_util', 'tools', 'tout'] +__all__ = ['checkpatch', 'commit', 'control', 'func_test', 'get_maintainer', + 'gitutil', '__main__', 'patchstream', 'project', 'series', + 'settings','setup', 'status', 'test_checkpatch', 'test_settings'] diff --git a/tools/patman/__main__.py b/tools/patman/__main__.py index 749e6348b66..30632559bb6 100755 --- a/tools/patman/__main__.py +++ b/tools/patman/__main__.py @@ -24,10 +24,10 @@ from patman import func_test from patman import gitutil from patman import project from patman import settings -from patman import terminal -from patman import test_util from patman import test_checkpatch -from patman import tools +from u_boot_pylib import terminal +from u_boot_pylib import test_util +from u_boot_pylib import tools
epilog = '''Create patches from commits in a branch, check them and email them as specified by tags you place in the commits. Use -n to do a dry run first.''' @@ -150,7 +150,7 @@ if args.cmd == 'test': result = test_util.run_test_suites( 'patman', False, False, False, None, None, None, [test_checkpatch.TestPatch, func_test.TestFunctional, - 'gitutil', 'settings', 'terminal']) + 'gitutil', 'settings'])
sys.exit(0 if result.wasSuccessful() else 1)
diff --git a/tools/patman/checkpatch.py b/tools/patman/checkpatch.py index d1b902dd962..c1dec323f36 100644 --- a/tools/patman/checkpatch.py +++ b/tools/patman/checkpatch.py @@ -7,9 +7,9 @@ import os import re import sys
-from patman import command from patman import gitutil -from patman import terminal +from u_boot_pylib import command +from u_boot_pylib import terminal
EMACS_PREFIX = r'(?:[0-9]{4}.*.patch:[0-9]+: )?' TYPE_NAME = r'([A-Z_]+:)?' diff --git a/tools/patman/control.py b/tools/patman/control.py index 38e98dab84d..d1bcea0c9a7 100644 --- a/tools/patman/control.py +++ b/tools/patman/control.py @@ -14,7 +14,7 @@ import sys from patman import checkpatch from patman import gitutil from patman import patchstream -from patman import terminal +from u_boot_pylib import terminal
def setup(): """Do required setup before doing anything""" diff --git a/tools/patman/func_test.py b/tools/patman/func_test.py index c25a47bdeb2..8c2dfbe4528 100644 --- a/tools/patman/func_test.py +++ b/tools/patman/func_test.py @@ -23,9 +23,9 @@ from patman import patchstream from patman.patchstream import PatchStream from patman.series import Series from patman import settings -from patman import terminal -from patman import tools -from patman.test_util import capture_sys_output +from u_boot_pylib import terminal +from u_boot_pylib import tools +from u_boot_pylib.test_util import capture_sys_output
import pygit2 from patman import status diff --git a/tools/patman/get_maintainer.py b/tools/patman/get_maintainer.py index f7011be1e49..8df3d124bac 100644 --- a/tools/patman/get_maintainer.py +++ b/tools/patman/get_maintainer.py @@ -7,8 +7,8 @@ import os import shlex import shutil
-from patman import command from patman import gitutil +from u_boot_pylib import command
def find_get_maintainer(script_file_name): diff --git a/tools/patman/gitutil.py b/tools/patman/gitutil.py index 5e742102c21..6700057359f 100644 --- a/tools/patman/gitutil.py +++ b/tools/patman/gitutil.py @@ -5,9 +5,9 @@ import os import sys
-from patman import command from patman import settings -from patman import terminal +from u_boot_pylib import command +from u_boot_pylib import terminal
# True to use --no-decorate - we check this in setup() use_no_decorate = True diff --git a/tools/patman/patchstream.py b/tools/patman/patchstream.py index fb6a6036f3b..f91669a9404 100644 --- a/tools/patman/patchstream.py +++ b/tools/patman/patchstream.py @@ -14,10 +14,10 @@ import queue import shutil import tempfile
-from patman import command from patman import commit from patman import gitutil from patman.series import Series +from u_boot_pylib import command
# Tags that we detect and remove RE_REMOVE = re.compile(r'^BUG=|^TEST=|^BRANCH=|^Review URL:' diff --git a/tools/patman/series.py b/tools/patman/series.py index 2eeeef71dc6..88417acb434 100644 --- a/tools/patman/series.py +++ b/tools/patman/series.py @@ -11,8 +11,8 @@ import os from patman import get_maintainer from patman import gitutil from patman import settings -from patman import terminal -from patman import tools +from u_boot_pylib import terminal +from u_boot_pylib import tools
# Series-xxx tags that we understand valid_series = ['to', 'cc', 'version', 'changes', 'prefix', 'notes', 'name', diff --git a/tools/patman/status.py b/tools/patman/status.py index 47ed6d61d4d..5fb436e08ff 100644 --- a/tools/patman/status.py +++ b/tools/patman/status.py @@ -18,8 +18,8 @@ import requests
from patman import patchstream from patman.patchstream import PatchStream -from patman import terminal -from patman import tout +from u_boot_pylib import terminal +from u_boot_pylib import tout
# Patches which are part of a multi-patch series are shown with a prefix like # [prefix, version, sequence], for example '[RFC, v2, 3/5]'. All but the last diff --git a/tools/patman/test_settings.py b/tools/patman/test_settings.py index c768a2fc641..06b7cbc3ab6 100644 --- a/tools/patman/test_settings.py +++ b/tools/patman/test_settings.py @@ -10,7 +10,7 @@ import sys import tempfile
from patman import settings -from patman import tools +from u_boot_pylib import tools
@contextlib.contextmanager diff --git a/tools/rmboard.py b/tools/rmboard.py index ae256321270..0c56b149e0f 100755 --- a/tools/rmboard.py +++ b/tools/rmboard.py @@ -28,7 +28,7 @@ import os import re import sys
-from patman import command +from u_boot_pylib import command
def rm_kconfig_include(path): """Remove a path from Kconfig files diff --git a/tools/u_boot_pylib/__init__.py b/tools/u_boot_pylib/__init__.py new file mode 100644 index 00000000000..63c88e85ec0 --- /dev/null +++ b/tools/u_boot_pylib/__init__.py @@ -0,0 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0+ + +__all__ = ['command', 'cros_subprocess','terminal', 'test_util', 'tools', + 'tout'] diff --git a/tools/u_boot_pylib/__main__.py b/tools/u_boot_pylib/__main__.py new file mode 100755 index 00000000000..8f98d7bd9f8 --- /dev/null +++ b/tools/u_boot_pylib/__main__.py @@ -0,0 +1,23 @@ +#!/usr/bin/env python3 +# SPDX-License-Identifier: GPL-2.0+ +# +# Copyright 2023 Google LLC +# + +import os +import sys + +if __name__ == "__main__": + # Allow 'from u_boot_pylib import xxx to work' + our_path = os.path.dirname(os.path.realpath(__file__)) + sys.path.append(os.path.join(our_path, '..')) + + # Run tests + from u_boot_pylib import terminal + from u_boot_pylib import test_util + + result = test_util.run_test_suites( + 'u_boot_pylib', False, False, False, None, None, None, + ['terminal']) + + sys.exit(0 if result.wasSuccessful() else 1) diff --git a/tools/patman/command.py b/tools/u_boot_pylib/command.py similarity index 99% rename from tools/patman/command.py rename to tools/u_boot_pylib/command.py index 92c453b5c13..9bbfc5bdd83 100644 --- a/tools/patman/command.py +++ b/tools/u_boot_pylib/command.py @@ -4,7 +4,7 @@
import os
-from patman import cros_subprocess +from u_boot_pylib import cros_subprocess
"""Shell command ease-ups for Python."""
diff --git a/tools/patman/cros_subprocess.py b/tools/u_boot_pylib/cros_subprocess.py similarity index 100% rename from tools/patman/cros_subprocess.py rename to tools/u_boot_pylib/cros_subprocess.py diff --git a/tools/patman/terminal.py b/tools/u_boot_pylib/terminal.py similarity index 100% rename from tools/patman/terminal.py rename to tools/u_boot_pylib/terminal.py diff --git a/tools/patman/test_util.py b/tools/u_boot_pylib/test_util.py similarity index 99% rename from tools/patman/test_util.py rename to tools/u_boot_pylib/test_util.py index 9e0811b61a2..e7564e10c99 100644 --- a/tools/patman/test_util.py +++ b/tools/u_boot_pylib/test_util.py @@ -11,7 +11,7 @@ import os import sys import unittest
-from patman import command +from u_boot_pylib import command
from io import StringIO
diff --git a/tools/patman/tools.py b/tools/u_boot_pylib/tools.py similarity index 99% rename from tools/patman/tools.py rename to tools/u_boot_pylib/tools.py index 2ac814d476f..187725b5015 100644 --- a/tools/patman/tools.py +++ b/tools/u_boot_pylib/tools.py @@ -11,8 +11,8 @@ import sys import tempfile import urllib.request
-from patman import command -from patman import tout +from u_boot_pylib import command +from u_boot_pylib import tout
# Output directly (generally this is temporary) outdir = None diff --git a/tools/patman/tout.py b/tools/u_boot_pylib/tout.py similarity index 99% rename from tools/patman/tout.py rename to tools/u_boot_pylib/tout.py index ff0fd92afcc..6bd2806f88f 100644 --- a/tools/patman/tout.py +++ b/tools/u_boot_pylib/tout.py @@ -6,7 +6,7 @@
import sys
-from patman import terminal +from u_boot_pylib import terminal
# Output verbosity levels that we support ERROR, WARNING, NOTICE, INFO, DETAIL, DEBUG = range(6) diff --git a/tools/u_boot_pylib/u_boot_pylib b/tools/u_boot_pylib/u_boot_pylib new file mode 120000 index 00000000000..5a427d19424 --- /dev/null +++ b/tools/u_boot_pylib/u_boot_pylib @@ -0,0 +1 @@ +__main__.py \ No newline at end of file

The patman directory has a number of modules which are used by other tools in U-Boot. This makes it hard to package the tools using pypi since the common files must be copied along with the tool that uses them.
To address this, move these files into a new u_boot_pylib library. This can be packaged separately and listed as a dependency of each tool.
Signed-off-by: Simon Glass sjg@chromium.org ---
(no changes since v1)
scripts/event_dump.py | 2 +- test/run | 1 + tools/binman/bintool.py | 8 +++---- tools/binman/bintool_test.py | 8 +++---- tools/binman/btool/lz4.py | 2 +- tools/binman/btool/lzma_alone.py | 2 +- tools/binman/cbfs_util.py | 4 ++-- tools/binman/cbfs_util_test.py | 4 ++-- tools/binman/control.py | 6 ++--- tools/binman/elf.py | 6 ++--- tools/binman/elf_test.py | 8 +++---- tools/binman/entry.py | 6 ++--- tools/binman/entry_test.py | 2 +- tools/binman/etype/_testing.py | 2 +- tools/binman/etype/atf_fip.py | 2 +- tools/binman/etype/blob.py | 4 ++-- tools/binman/etype/blob_ext.py | 4 ++-- tools/binman/etype/blob_ext_list.py | 4 ++-- tools/binman/etype/fdtmap.py | 4 ++-- tools/binman/etype/files.py | 2 +- tools/binman/etype/fill.py | 2 +- tools/binman/etype/fit.py | 2 +- tools/binman/etype/fmap.py | 6 ++--- tools/binman/etype/gbb.py | 4 ++-- tools/binman/etype/intel_ifwi.py | 2 +- tools/binman/etype/mkimage.py | 2 +- tools/binman/etype/null.py | 2 +- tools/binman/etype/pre_load.py | 2 +- tools/binman/etype/section.py | 6 ++--- tools/binman/etype/text.py | 2 +- tools/binman/etype/u_boot_dtb_with_ucode.py | 2 +- tools/binman/etype/u_boot_elf.py | 2 +- tools/binman/etype/u_boot_env.py | 2 +- tools/binman/etype/u_boot_spl_bss_pad.py | 2 +- tools/binman/etype/u_boot_spl_expanded.py | 2 +- tools/binman/etype/u_boot_tpl_bss_pad.py | 2 +- tools/binman/etype/u_boot_tpl_expanded.py | 2 +- .../binman/etype/u_boot_tpl_with_ucode_ptr.py | 4 ++-- tools/binman/etype/u_boot_ucode.py | 2 +- tools/binman/etype/u_boot_vpl_bss_pad.py | 2 +- tools/binman/etype/u_boot_vpl_expanded.py | 2 +- tools/binman/etype/u_boot_with_ucode_ptr.py | 4 ++-- tools/binman/etype/vblock.py | 2 +- tools/binman/fdt_test.py | 2 +- tools/binman/fip_util.py | 4 ++-- tools/binman/fip_util_test.py | 4 ++-- tools/binman/fmap_util.py | 2 +- tools/binman/ftest.py | 8 +++---- tools/binman/image.py | 4 ++-- tools/binman/image_test.py | 2 +- tools/binman/main.py | 7 +++--- tools/binman/state.py | 4 ++-- tools/buildman/builder.py | 6 ++--- tools/buildman/builderthread.py | 2 +- tools/buildman/cfgutil.py | 2 +- tools/buildman/control.py | 8 +++---- tools/buildman/func_test.py | 8 +++---- tools/buildman/main.py | 4 ++-- tools/buildman/test.py | 8 +++---- tools/buildman/toolchain.py | 6 ++--- tools/dtoc/fdt.py | 2 +- tools/dtoc/fdt_util.py | 4 ++-- tools/dtoc/main.py | 5 ++-- tools/dtoc/test_dtoc.py | 4 ++-- tools/dtoc/test_fdt.py | 7 +++--- tools/dtoc/test_src_scan.py | 4 ++-- tools/patman/__init__.py | 7 +++--- tools/patman/__main__.py | 8 +++---- tools/patman/checkpatch.py | 4 ++-- tools/patman/control.py | 2 +- tools/patman/func_test.py | 6 ++--- tools/patman/get_maintainer.py | 2 +- tools/patman/gitutil.py | 4 ++-- tools/patman/patchstream.py | 2 +- tools/patman/series.py | 4 ++-- tools/patman/status.py | 4 ++-- tools/patman/test_settings.py | 2 +- tools/rmboard.py | 2 +- tools/u_boot_pylib/__init__.py | 4 ++++ tools/u_boot_pylib/__main__.py | 23 +++++++++++++++++++ tools/{patman => u_boot_pylib}/command.py | 2 +- .../cros_subprocess.py | 0 tools/{patman => u_boot_pylib}/terminal.py | 0 tools/{patman => u_boot_pylib}/test_util.py | 2 +- tools/{patman => u_boot_pylib}/tools.py | 4 ++-- tools/{patman => u_boot_pylib}/tout.py | 2 +- tools/u_boot_pylib/u_boot_pylib | 1 + 87 files changed, 182 insertions(+), 151 deletions(-) create mode 100644 tools/u_boot_pylib/__init__.py create mode 100755 tools/u_boot_pylib/__main__.py rename tools/{patman => u_boot_pylib}/command.py (99%) rename tools/{patman => u_boot_pylib}/cros_subprocess.py (100%) rename tools/{patman => u_boot_pylib}/terminal.py (100%) rename tools/{patman => u_boot_pylib}/test_util.py (99%) rename tools/{patman => u_boot_pylib}/tools.py (99%) rename tools/{patman => u_boot_pylib}/tout.py (99%) create mode 120000 tools/u_boot_pylib/u_boot_pylib
Applied to u-boot-dm/next, thanks!

Create a script which can package a tool for use with PyPi and the 'pip' tool. This involves quite a few steps so is best automated. Future work will enable use of this for some of the tools in U-Boot.
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v2: - Drop test files - Fix removable of the /tmp dir - Quite a few updates to make things work with the new names
scripts/make_pip.sh | 117 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 117 insertions(+) create mode 100755 scripts/make_pip.sh
diff --git a/scripts/make_pip.sh b/scripts/make_pip.sh new file mode 100755 index 00000000000..4602dcf61c8 --- /dev/null +++ b/scripts/make_pip.sh @@ -0,0 +1,117 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0+ + +# Packages a U-Boot tool +# +# Usage: make_pip.sh <tool_name> [--real] +# +# Where tool_name is one of patman, buildman, dtoc, binman, u_boot_pylib +# +# and --real means to upload to the real server (otherwise the test one is used) +# +# The username for upload is always __token__ so set TWINE_PASSWORD to your +# password before running this script: +# +# export TWINE_PASSWORD=pypi-xxx +# +# To test your new packages: +# +# pip install -i https://test.pypi.org/simple/ <tool_name> +# + +# DO NOT use patman or binman + +set -xe + +# Repo to upload to +repo="--repository testpypi" + +# Non-empty to do the actual upload +upload=1 + +tool="$1" +shift +flags="$*" + +if [[ "${tool}" =~ ^(patman|buildman|dtoc|binman|u_boot_pylib)$ ]]; then + echo "Building dist package for tool ${tool}" +else + echo "Unknown tool ${tool}: use patman, buildman, dtoc or binman" + exit 1 +fi + +for flag in "${flags}"; do + if [ "${flag}" == "--real" ]; then + echo "Using real server" + repo= + fi + if [ "${flag}" == "-n" ]; then + echo "Doing dry run" + upload= + fi +done + +if [ -n "${upload}" ]; then + if [ -z "${TWINE_PASSWORD}" ]; then + echo "Please set TWINE_PASSWORD to your password and retry" + exit 1 + fi +fi + +# Create a temp dir to work in +dir=$(mktemp -d) + +# Copy in some basic files +cp -v tools/${tool}/pyproject.toml ${dir} +cp -v Licenses/gpl-2.0.txt ${dir}/LICENSE +readme="tools/${tool}/README.*" + +# Copy in the README, dropping some Sphinx constructs that PyPi doesn't like +cat ${readme} | sed -E 's/:(doc|ref):`.*`//; /sectionauthor/d; /toctree::/d' \ + > ${dir}/$(basename ${readme}) + +# Copy the top-level Python and doc files +dest=${dir}/src/${tool} +mkdir -p ${dest} +cp -v tools/$tool/{*.py,*.rst} ${dest} + +# Copy over the subdirectories, including any sub files. Drop any cache files +# and other such things +pushd tools/${tool} +for subdir in $(find . -maxdepth 1 -type d | \ + grep -vE "(__pycache__|home|usr|scratch|.$|pyproject)"); do + pathname="${dest}/${subdir}" + echo "Copy ${pathname}" + cp -a ${subdir} ${pathname} +done +popd + +# Remove cache files that accidentally made it through +find ${dest} -name __pycache__ -type f -exec rm {} ; +find ${dest} -depth -name __pycache__ -exec rmdir 112 ; + +# Remove test files +rm -rf ${dest}/*test* + +mkdir ${dir}/tests +cd ${dir} + +# Make sure the tools are up to date +python3 -m pip install --upgrade build +python3 -m pip install --upgrade twine + +# Build the PyPi package +python3 -m build + +echo "Completed build of ${tool}" + +# Use --skip-existing to work even if the version is already present +if [ -n "${upload}" ]; then + echo "Uploading from ${dir}" + python3 -m twine upload ${repo} -u __token__ dist/* + echo "Completed upload of ${tool}" +fi + +rm -rf "${dir}" + +echo -e "done\n\n"

Create a script which can package a tool for use with PyPi and the 'pip' tool. This involves quite a few steps so is best automated. Future work will enable use of this for some of the tools in U-Boot.
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v2: - Drop test files - Fix removable of the /tmp dir - Quite a few updates to make things work with the new names
scripts/make_pip.sh | 117 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 117 insertions(+) create mode 100755 scripts/make_pip.sh
Applied to u-boot-dm/next, thanks!

Create the necessary files to build this new package.
Signed-off-by: Simon Glass sjg@chromium.org ---
(no changes since v1)
Makefile | 18 +- tools/u_boot_pylib/LICENSE | 339 ++++++++++++++++++++++++++++++ tools/u_boot_pylib/README.rst | 15 ++ tools/u_boot_pylib/pyproject.toml | 22 ++ 4 files changed, 393 insertions(+), 1 deletion(-) create mode 100644 tools/u_boot_pylib/LICENSE create mode 100644 tools/u_boot_pylib/README.rst create mode 100644 tools/u_boot_pylib/pyproject.toml
diff --git a/Makefile b/Makefile index 54f894dab84..9f008dea0ec 100644 --- a/Makefile +++ b/Makefile @@ -522,7 +522,7 @@ env_h := include/generated/environment.h no-dot-config-targets := clean clobber mrproper distclean \ help %docs check% coccicheck \ ubootversion backup tests check pcheck qcheck tcheck \ - pylint pylint_err + pylint pylint_err _pip pip pip_test pip_release
config-targets := 0 mixed-targets := 0 @@ -2272,6 +2272,17 @@ backup: F=`basename $(srctree)` ; cd .. ; \ gtar --force-local -zcvf `LC_ALL=C date "+$$F-%Y-%m-%d-%T.tar.gz"` $$F
+PHONY += _pip pip pip_release + +pip_release: PIP_ARGS="--real" +pip_test: PIP_ARGS="" +pip: PIP_ARGS="-n" + +pip pip_test pip_release: _pip + +_pip: + scripts/make_pip.sh u_boot_pylib ${PIP_ARGS} + help: @echo 'Cleaning targets:' @echo ' clean - Remove most generated files but keep the config' @@ -2305,6 +2316,11 @@ help: @echo " cfg - Don't build, just create the .cfg files" @echo " envtools - Build only the target-side environment tools" @echo '' + @echo 'PyPi / pip targets:' + @echo ' pip - Check building of PyPi packages' + @echo ' pip_test - Build PyPi pakages and upload to test server' + @echo ' pip_release - Build PyPi pakages and upload to release server' + @echo '' @echo 'Static analysers' @echo ' checkstack - Generate a list of stack hogs' @echo ' coccicheck - Execute static code analysis with Coccinelle' diff --git a/tools/u_boot_pylib/LICENSE b/tools/u_boot_pylib/LICENSE new file mode 100644 index 00000000000..d159169d105 --- /dev/null +++ b/tools/u_boot_pylib/LICENSE @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + <one line to give the program's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + <signature of Ty Coon>, 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. diff --git a/tools/u_boot_pylib/README.rst b/tools/u_boot_pylib/README.rst new file mode 100644 index 00000000000..93858f5571d --- /dev/null +++ b/tools/u_boot_pylib/README.rst @@ -0,0 +1,15 @@ +.. SPDX-License-Identifier: GPL-2.0+ + +# U-Boot Python Library +===================== + +This is a Python library used by various U-Boot tools, including patman, +buildman and binman. + +The module can be installed with pip:: + + pip install u_boot_pylib + +or via setup.py:: + + ./setup.py install [--user] diff --git a/tools/u_boot_pylib/pyproject.toml b/tools/u_boot_pylib/pyproject.toml new file mode 100644 index 00000000000..3f33caf6f8d --- /dev/null +++ b/tools/u_boot_pylib/pyproject.toml @@ -0,0 +1,22 @@ +[build-system] +requires = ["setuptools>=61.0"] +build-backend = "setuptools.build_meta" + +[project] +name = "u_boot_pylib" +version = "0.0.2" +authors = [ + { name="Simon Glass", email="sjg@chromium.org" }, +] +description = "U-Boot python library" +readme = "README.md" +requires-python = ">=3.7" +classifiers = [ + "Programming Language :: Python :: 3", + "License :: OSI Approved :: GNU General Public License v2 or later (GPLv2+)", + "Operating System :: OS Independent", +] + +[project.urls] +"Homepage" = "https://u-boot.readthedocs.io" +"Bug Tracker" = "https://source.denx.de/groups/u-boot/-/issues"

Create the necessary files to build this new package.
Signed-off-by: Simon Glass sjg@chromium.org ---
(no changes since v1)
Makefile | 18 +- tools/u_boot_pylib/LICENSE | 339 ++++++++++++++++++++++++++++++ tools/u_boot_pylib/README.rst | 15 ++ tools/u_boot_pylib/pyproject.toml | 22 ++ 4 files changed, 393 insertions(+), 1 deletion(-) create mode 100644 tools/u_boot_pylib/LICENSE create mode 100644 tools/u_boot_pylib/README.rst create mode 100644 tools/u_boot_pylib/pyproject.toml
Applied to u-boot-dm/next, thanks!

Tests are not packaged with patman so this file will not be accessible when installing with pip. Move the import later in the file, when we know the file is present.
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v2: - Add new patch to avoid importing test_checkpatch before it is needed
tools/patman/__main__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/patman/__main__.py b/tools/patman/__main__.py index 30632559bb6..48ffbc8eadf 100755 --- a/tools/patman/__main__.py +++ b/tools/patman/__main__.py @@ -24,7 +24,6 @@ from patman import func_test from patman import gitutil from patman import project from patman import settings -from patman import test_checkpatch from u_boot_pylib import terminal from u_boot_pylib import test_util from u_boot_pylib import tools @@ -146,6 +145,7 @@ if not args.debug: # Run our meagre tests if args.cmd == 'test': from patman import func_test + from patman import test_checkpatch
result = test_util.run_test_suites( 'patman', False, False, False, None, None, None,

Tests are not packaged with patman so this file will not be accessible when installing with pip. Move the import later in the file, when we know the file is present.
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v2: - Add new patch to avoid importing test_checkpatch before it is needed
tools/patman/__main__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
Applied to u-boot-dm/next, thanks!

Create the necessary files to build this new package.
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v2: - Rename the package to patch-manager
Makefile | 1 + tools/patman/pyproject.toml | 29 +++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+) create mode 100644 tools/patman/pyproject.toml
diff --git a/Makefile b/Makefile index 9f008dea0ec..abd8d60a1bb 100644 --- a/Makefile +++ b/Makefile @@ -2282,6 +2282,7 @@ pip pip_test pip_release: _pip
_pip: scripts/make_pip.sh u_boot_pylib ${PIP_ARGS} + scripts/make_pip.sh patman ${PIP_ARGS}
help: @echo 'Cleaning targets:' diff --git a/tools/patman/pyproject.toml b/tools/patman/pyproject.toml new file mode 100644 index 00000000000..c5dc7c7e276 --- /dev/null +++ b/tools/patman/pyproject.toml @@ -0,0 +1,29 @@ +[build-system] +requires = ["setuptools>=61.0"] +build-backend = "setuptools.build_meta" + +[project] +name = "patch-manager" +version = "0.0.2" +authors = [ + { name="Simon Glass", email="sjg@chromium.org" }, +] +dependencies = ["u_boot_pylib"] +description = "Patman patch manager" +readme = "README.rst" +requires-python = ">=3.7" +classifiers = [ + "Programming Language :: Python :: 3", + "License :: OSI Approved :: GNU General Public License v2 or later (GPLv2+)", + "Operating System :: OS Independent", +] + +[project.urls] +"Homepage" = "https://u-boot.readthedocs.io/en/latest/develop/patman.html" +"Bug Tracker" = "https://source.denx.de/groups/u-boot/-/issues" + +[project.scripts] +patman = "patman.__main__:run_patman" + +[tool.setuptools.package-data] +patman = ["*.rst"]

Create the necessary files to build this new package.
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v2: - Rename the package to patch-manager
Makefile | 1 + tools/patman/pyproject.toml | 29 +++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+) create mode 100644 tools/patman/pyproject.toml
Applied to u-boot-dm/next, thanks!

Put this code into a function so it is easy for it be run when packaged.
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v2: - Add patch to split out the main code into a function
tools/buildman/main.py | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-)
diff --git a/tools/buildman/main.py b/tools/buildman/main.py index 6076ba5d63d..5e1f68d8235 100755 --- a/tools/buildman/main.py +++ b/tools/buildman/main.py @@ -46,17 +46,22 @@ def RunTests(skip_net_tests, verboose, args):
return (0 if result.wasSuccessful() else 1)
-options, args = cmdline.ParseArgs() +def run_buildman(): + options, args = cmdline.ParseArgs()
-if not options.debug: - sys.tracebacklimit = 0 + if not options.debug: + sys.tracebacklimit = 0
-# Run our meagre tests -if options.test: - RunTests(options.skip_net_tests, options.verbose, args) + # Run our meagre tests + if cmdline.HAS_TESTS and options.test: + RunTests(options.skip_net_tests, options.verbose, args)
-# Build selected commits for selected boards -else: - bsettings.Setup(options.config_file) - ret_code = control.DoBuildman(options, args) - sys.exit(ret_code) + # Build selected commits for selected boards + else: + bsettings.Setup(options.config_file) + ret_code = control.DoBuildman(options, args) + sys.exit(ret_code) + + +if __name__ == "__main__": + run_buildman()

Put this code into a function so it is easy for it be run when packaged.
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v2: - Add patch to split out the main code into a function
tools/buildman/main.py | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-)
Applied to u-boot-dm/next, thanks!

It doesn't make much sense to expose tests when buildman is running outside of the U-Boot git checkout. Hide the option in this case
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v2: - Add a patch to hide the test options unless test code is available
tools/buildman/cmdline.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-)
diff --git a/tools/buildman/cmdline.py b/tools/buildman/cmdline.py index c485994e9fe..e22aaf6c7bc 100644 --- a/tools/buildman/cmdline.py +++ b/tools/buildman/cmdline.py @@ -3,6 +3,11 @@ #
from optparse import OptionParser +import os +import pathlib + +BUILDMAN_DIR = pathlib.Path(__file__).parent +HAS_TESTS = os.path.exists(BUILDMAN_DIR / "test.py")
def ParseArgs(): """Parse command line arguments from sys.argv[] @@ -101,12 +106,13 @@ def ParseArgs(): default=False, help='Show a build summary') parser.add_option('-S', '--show-sizes', action='store_true', default=False, help='Show image size variation in summary') - parser.add_option('--skip-net-tests', action='store_true', default=False, - help='Skip tests which need the network') parser.add_option('--step', type='int', default=1, help='Only build every n commits (0=just first and last)') - parser.add_option('-t', '--test', action='store_true', dest='test', - default=False, help='run tests') + if HAS_TESTS: + parser.add_option('--skip-net-tests', action='store_true', default=False, + help='Skip tests which need the network') + parser.add_option('-t', '--test', action='store_true', dest='test', + default=False, help='run tests') parser.add_option('-T', '--threads', type='int', default=None, help='Number of builder threads to use (0=single-thread)')

It doesn't make much sense to expose tests when buildman is running outside of the U-Boot git checkout. Hide the option in this case
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v2: - Add a patch to hide the test options unless test code is available
tools/buildman/cmdline.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-)
Applied to u-boot-dm/next, thanks!

Using 'str' as a variable makes it impossible to use it as a type in the same function. Fix this by using a different name.
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v2: - Add patch to fix use of a type as a variable
tools/buildman/control.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/tools/buildman/control.py b/tools/buildman/control.py index 76e4e2709ac..fe3b6fa335d 100644 --- a/tools/buildman/control.py +++ b/tools/buildman/control.py @@ -261,9 +261,9 @@ def DoBuildman(options, args, toolchains=None, make_func=None, brds=None, count += 1 # Build upstream commit also
if not count: - str = ("No commits found to process in branch '%s': " + msg = ("No commits found to process in branch '%s': " "set branch's upstream or use -c flag" % options.branch) - sys.exit(col.build(col.RED, str)) + sys.exit(col.build(col.RED, msg)) if options.work_in_output: if len(selected) != 1: sys.exit(col.build(col.RED,

Using 'str' as a variable makes it impossible to use it as a type in the same function. Fix this by using a different name.
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v2: - Add patch to fix use of a type as a variable
tools/buildman/control.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
Applied to u-boot-dm/next, thanks!

Use this function so that the help can be found even when buildman is running from a package.
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v2: - Add new patch to use importlib to find the help
tools/buildman/control.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/tools/buildman/control.py b/tools/buildman/control.py index fe3b6fa335d..07251b52179 100644 --- a/tools/buildman/control.py +++ b/tools/buildman/control.py @@ -3,6 +3,7 @@ #
import multiprocessing +import importlib.resources import os import shutil import subprocess @@ -152,9 +153,8 @@ def DoBuildman(options, args, toolchains=None, make_func=None, brds=None, global builder
if options.full_help: - tools.print_full_help( - os.path.join(os.path.dirname(os.path.realpath(sys.argv[0])), - 'README.rst')) + with importlib.resources.path('buildman', 'README.rst') as readme: + tools.print_full_help(str(readme)) return 0
gitutil.setup()

Use this function so that the help can be found even when buildman is running from a package.
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v2: - Add new patch to use importlib to find the help
tools/buildman/control.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
Applied to u-boot-dm/next, thanks!

Create the necessary files to build this new package.
It is not actually clear whether this is useful, since buildman has no purpose outside U-Boot. It is included for completeness, since adding this later would be more trouble.
Move the main program into a function so that it can easily be called by the PyPi-created script.
Signed-off-by: Simon Glass sjg@chromium.org ---
(no changes since v1)
Makefile | 1 + tools/buildman/pyproject.toml | 29 +++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+) create mode 100644 tools/buildman/pyproject.toml
diff --git a/Makefile b/Makefile index abd8d60a1bb..3c1bda50263 100644 --- a/Makefile +++ b/Makefile @@ -2283,6 +2283,7 @@ pip pip_test pip_release: _pip _pip: scripts/make_pip.sh u_boot_pylib ${PIP_ARGS} scripts/make_pip.sh patman ${PIP_ARGS} + scripts/make_pip.sh buildman ${PIP_ARGS}
help: @echo 'Cleaning targets:' diff --git a/tools/buildman/pyproject.toml b/tools/buildman/pyproject.toml new file mode 100644 index 00000000000..4d75e772ee1 --- /dev/null +++ b/tools/buildman/pyproject.toml @@ -0,0 +1,29 @@ +[build-system] +requires = ["setuptools>=61.0"] +build-backend = "setuptools.build_meta" + +[project] +name = "buildman" +version = "0.0.2" +authors = [ + { name="Simon Glass", email="sjg@chromium.org" }, +] +dependencies = ["u_boot_pylib", "patch-manager"] +description = "Buildman build tool for U-Boot" +readme = "README.rst" +requires-python = ">=3.7" +classifiers = [ + "Programming Language :: Python :: 3", + "License :: OSI Approved :: GNU General Public License v2 or later (GPLv2+)", + "Operating System :: OS Independent", +] + +[project.urls] +"Homepage" = "https://u-boot.readthedocs.io/en/latest/build/buildman.html" +"Bug Tracker" = "https://source.denx.de/groups/u-boot/-/issues" + +[project.scripts] +buildman = "buildman.main:run_buildman" + +[tool.setuptools.package-data] +buildman = ["*.rst"]

Create the necessary files to build this new package.
It is not actually clear whether this is useful, since buildman has no purpose outside U-Boot. It is included for completeness, since adding this later would be more trouble.
Move the main program into a function so that it can easily be called by the PyPi-created script.
Signed-off-by: Simon Glass sjg@chromium.org ---
(no changes since v1)
Makefile | 1 + tools/buildman/pyproject.toml | 29 +++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+) create mode 100644 tools/buildman/pyproject.toml
Applied to u-boot-dm/next, thanks!

It doesn't make much sense to expose tests when dtoc is running outside of the U-Boot git checkout. Hide the option in this case.
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v2: - Add a patch to hide the test options unless test code is available
tools/dtoc/main.py | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-)
diff --git a/tools/dtoc/main.py b/tools/dtoc/main.py index fc9207d1b63..91521661f46 100755 --- a/tools/dtoc/main.py +++ b/tools/dtoc/main.py @@ -23,6 +23,7 @@ see doc/driver-model/of-plat.rst
from argparse import ArgumentParser import os +import pathlib import sys
# Bring in the patman libraries @@ -37,6 +38,9 @@ sys.path.insert(0, os.path.join(our_path, from dtoc import dtb_platdata from u_boot_pylib import test_util
+DTOC_DIR = pathlib.Path(__file__).parent +HAVE_TESTS = (DTOC_DIR / 'test_dtoc.py').exists() + def run_tests(processes, args): """Run all the test we have for dtoc
@@ -93,19 +97,22 @@ parser.add_argument('-p', '--phase', type=str, help='set phase of U-Boot this invocation is for (spl/tpl)') parser.add_argument('-P', '--processes', type=int, help='set number of processes to use for running tests') -parser.add_argument('-t', '--test', action='store_true', dest='test', - default=False, help='run tests') -parser.add_argument('-T', '--test-coverage', action='store_true', - default=False, help='run tests and check for 100%% coverage') +if HAVE_TESTS: + parser.add_argument('-t', '--test', action='store_true', dest='test', + default=False, help='run tests') + parser.add_argument( + '-T', '--test-coverage', action='store_true', + default=False, help='run tests and check for 100%% coverage') + parser.add_argument('files', nargs='*') args = parser.parse_args()
# Run our meagre tests -if args.test: +if HAVE_TESTS and args.test: ret_code = run_tests(args.processes, args) sys.exit(ret_code)
-elif args.test_coverage: +elif HAVE_TESTS and args.test_coverage: RunTestCoverage()
else:

It doesn't make much sense to expose tests when dtoc is running outside of the U-Boot git checkout. Hide the option in this case.
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v2: - Add a patch to hide the test options unless test code is available
tools/dtoc/main.py | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-)
Applied to u-boot-dm/next, thanks!

Put this code into a function so it is easy for it be run when packaged.
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v2: - Add patch to split out the main code into a function
tools/dtoc/main.py | 100 +++++++++++++++++++++++---------------------- 1 file changed, 52 insertions(+), 48 deletions(-)
diff --git a/tools/dtoc/main.py b/tools/dtoc/main.py index 91521661f46..6c91450410e 100755 --- a/tools/dtoc/main.py +++ b/tools/dtoc/main.py @@ -65,58 +65,62 @@ def run_tests(processes, args): return (0 if result.wasSuccessful() else 1)
-def RunTestCoverage(): +def RunTestCoverage(build_dir): """Run the tests and check that we get 100% coverage""" sys.argv = [sys.argv[0]] test_util.run_test_coverage('tools/dtoc/dtoc', '/main.py', ['tools/patman/*.py', 'tools/u_boot_pylib/*','*/fdt*', '*test*'], - args.build_dir) - - -if __name__ != '__main__': - sys.exit(1) - -epilog = '''Generate C code from devicetree files. See of-plat.rst for details''' - -parser = ArgumentParser(epilog=epilog) -parser.add_argument('-B', '--build-dir', type=str, default='b', - help='Directory containing the build output') -parser.add_argument('-c', '--c-output-dir', action='store', - help='Select output directory for C files') -parser.add_argument('-C', '--h-output-dir', action='store', - help='Select output directory for H files (defaults to --c-output-di)') -parser.add_argument('-d', '--dtb-file', action='store', - help='Specify the .dtb input file') -parser.add_argument('-i', '--instantiate', action='store_true', default=False, - help='Instantiate devices to avoid needing device_bind()') -parser.add_argument('--include-disabled', action='store_true', - help='Include disabled nodes') -parser.add_argument('-o', '--output', action='store', - help='Select output filename') -parser.add_argument('-p', '--phase', type=str, - help='set phase of U-Boot this invocation is for (spl/tpl)') -parser.add_argument('-P', '--processes', type=int, - help='set number of processes to use for running tests') -if HAVE_TESTS: - parser.add_argument('-t', '--test', action='store_true', dest='test', - default=False, help='run tests') - parser.add_argument( - '-T', '--test-coverage', action='store_true', - default=False, help='run tests and check for 100%% coverage') - -parser.add_argument('files', nargs='*') -args = parser.parse_args() + build_dir)
-# Run our meagre tests -if HAVE_TESTS and args.test: - ret_code = run_tests(args.processes, args) - sys.exit(ret_code)
-elif HAVE_TESTS and args.test_coverage: - RunTestCoverage() +def run_dtoc(): + epilog = 'Generate C code from devicetree files. See of-plat.rst for details'
-else: - dtb_platdata.run_steps(args.files, args.dtb_file, args.include_disabled, - args.output, - [args.c_output_dir, args.h_output_dir], - args.phase, instantiate=args.instantiate) + parser = ArgumentParser(epilog=epilog) + parser.add_argument('-B', '--build-dir', type=str, default='b', + help='Directory containing the build output') + parser.add_argument('-c', '--c-output-dir', action='store', + help='Select output directory for C files') + parser.add_argument( + '-C', '--h-output-dir', action='store', + help='Select output directory for H files (defaults to --c-output-di)') + parser.add_argument('-d', '--dtb-file', action='store', + help='Specify the .dtb input file') + parser.add_argument( + '-i', '--instantiate', action='store_true', default=False, + help='Instantiate devices to avoid needing device_bind()') + parser.add_argument('--include-disabled', action='store_true', + help='Include disabled nodes') + parser.add_argument('-o', '--output', action='store', + help='Select output filename') + parser.add_argument( + '-p', '--phase', type=str, + help='set phase of U-Boot this invocation is for (spl/tpl)') + parser.add_argument('-P', '--processes', type=int, + help='set number of processes to use for running tests') + if HAVE_TESTS: + parser.add_argument('-t', '--test', action='store_true', dest='test', + default=False, help='run tests') + parser.add_argument( + '-T', '--test-coverage', action='store_true', + default=False, help='run tests and check for 100%% coverage') + parser.add_argument('files', nargs='*') + args = parser.parse_args() + + # Run our meagre tests + if HAVE_TESTS and args.test: + ret_code = run_tests(args.processes, args) + sys.exit(ret_code) + + elif HAVE_TESTS and args.test_coverage: + RunTestCoverage(args.build_dir) + + else: + dtb_platdata.run_steps(args.files, args.dtb_file, args.include_disabled, + args.output, + [args.c_output_dir, args.h_output_dir], + args.phase, instantiate=args.instantiate) + + +if __name__ == '__main__': + run_dtoc()

Put this code into a function so it is easy for it be run when packaged.
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v2: - Add patch to split out the main code into a function
tools/dtoc/main.py | 100 +++++++++++++++++++++++---------------------- 1 file changed, 52 insertions(+), 48 deletions(-)
Applied to u-boot-dm/next, thanks!

Update this so that the directory being used is declared at the top of the file. Use pathlib as it seems to be more modern.
Signed-off-by: Simon Glass sjg@chromium.org ---
(no changes since v1)
tools/dtoc/test_dtoc.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/tools/dtoc/test_dtoc.py b/tools/dtoc/test_dtoc.py index 0f544f9f54a..597c93e8a87 100755 --- a/tools/dtoc/test_dtoc.py +++ b/tools/dtoc/test_dtoc.py @@ -13,6 +13,7 @@ import collections import copy import glob import os +import pathlib import struct import unittest
@@ -28,7 +29,8 @@ from dtoc.src_scan import get_compat_name from u_boot_pylib import test_util from u_boot_pylib import tools
-OUR_PATH = os.path.dirname(os.path.realpath(__file__)) +DTOC_DIR = pathlib.Path(__file__).parent +TEST_DATA_DIR = DTOC_DIR / 'test/'
HEADER = '''/* @@ -91,7 +93,7 @@ def get_dtb_file(dts_fname, capture_stderr=False): Returns: str: Filename of compiled file in output directory """ - return fdt_util.EnsureCompiled(os.path.join(OUR_PATH, 'test', dts_fname), + return fdt_util.EnsureCompiled(str(TEST_DATA_DIR / dts_fname), capture_stderr=capture_stderr)

Update this so that the directory being used is declared at the top of the file. Use pathlib as it seems to be more modern.
Signed-off-by: Simon Glass sjg@chromium.org ---
(no changes since v1)
tools/dtoc/test_dtoc.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
Applied to u-boot-dm/next, thanks!

Create the necessary files to build this new package.
This is needed for binman.
Move the main program into a function so that it can easily be called by the PyPi-created script.
Signed-off-by: Simon Glass sjg@chromium.org ---
(no changes since v1)
Makefile | 1 + tools/dtoc/README.rst | 15 +++++++++++++++ tools/dtoc/pyproject.toml | 26 ++++++++++++++++++++++++++ 3 files changed, 42 insertions(+) create mode 100644 tools/dtoc/README.rst create mode 100644 tools/dtoc/pyproject.toml
diff --git a/Makefile b/Makefile index 3c1bda50263..3951edabce1 100644 --- a/Makefile +++ b/Makefile @@ -2284,6 +2284,7 @@ _pip: scripts/make_pip.sh u_boot_pylib ${PIP_ARGS} scripts/make_pip.sh patman ${PIP_ARGS} scripts/make_pip.sh buildman ${PIP_ARGS} + scripts/make_pip.sh dtoc ${PIP_ARGS}
help: @echo 'Cleaning targets:' diff --git a/tools/dtoc/README.rst b/tools/dtoc/README.rst new file mode 100644 index 00000000000..92b39759ed1 --- /dev/null +++ b/tools/dtoc/README.rst @@ -0,0 +1,15 @@ +.. SPDX-License-Identifier: GPL-2.0+ + +Devicetree-to-C generator +========================= + +This is a Python program and associated utilities, which supports converting +devicetree files into C code. It generates header files containing struct +definitions, as well as C files containing the data. It does not require any +modification of the devicetree files. + +Some high-level libraries are provided for working with devicetree. These may +be useful in other projects. + +This package also includes some U-Boot-specific features, such as creating +`struct udevice` and `struct uclass` entries for devicetree nodes. diff --git a/tools/dtoc/pyproject.toml b/tools/dtoc/pyproject.toml new file mode 100644 index 00000000000..77fe4da2158 --- /dev/null +++ b/tools/dtoc/pyproject.toml @@ -0,0 +1,26 @@ +[build-system] +requires = ["setuptools>=61.0"] +build-backend = "setuptools.build_meta" + +[project] +name = "dtoc" +version = "0.0.2" +authors = [ + { name="Simon Glass", email="sjg@chromium.org" }, +] +dependencies = ["pylibfdt", "u_boot_pylib"] +description = "Devicetree-to-C generator" +readme = "README.rst" +requires-python = ">=3.7" +classifiers = [ + "Programming Language :: Python :: 3", + "License :: OSI Approved :: GNU General Public License v2 or later (GPLv2+)", + "Operating System :: OS Independent", +] + +[project.urls] +"Homepage" = "https://u-boot.readthedocs.io/en/latest/develop/driver-model/of-plat.html" +"Bug Tracker" = "https://source.denx.de/groups/u-boot/-/issues" + +[project.scripts] +dtoc = "dtoc.main:run_dtoc"

Create the necessary files to build this new package.
This is needed for binman.
Move the main program into a function so that it can easily be called by the PyPi-created script.
Signed-off-by: Simon Glass sjg@chromium.org ---
(no changes since v1)
Makefile | 1 + tools/dtoc/README.rst | 15 +++++++++++++++ tools/dtoc/pyproject.toml | 26 ++++++++++++++++++++++++++ 3 files changed, 42 insertions(+) create mode 100644 tools/dtoc/README.rst create mode 100644 tools/dtoc/pyproject.toml
Applied to u-boot-dm/next, thanks!

Put this code into a function so it is easy for it be run when packaged.
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v2: - Add patch to split out the main code into a function
tools/binman/main.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/tools/binman/main.py b/tools/binman/main.py index eef17b7b55f..92d2431aea7 100755 --- a/tools/binman/main.py +++ b/tools/binman/main.py @@ -85,7 +85,7 @@ def RunTests(debug, verbosity, processes, test_preserve_dirs, args, toolpath):
return (0 if result.wasSuccessful() else 1)
-def RunTestCoverage(toolpath): +def RunTestCoverage(toolpath, build_dir): """Run the tests and check that we get 100% coverage""" glob_list = control.GetEntryModules(False) all_set = set([os.path.splitext(os.path.basename(item))[0] @@ -97,7 +97,7 @@ def RunTestCoverage(toolpath): test_util.run_test_coverage('tools/binman/binman', None, ['*test*', '*main.py', 'tools/patman/*', 'tools/dtoc/*', 'tools/u_boot_pylib/*'], - args.build_dir, all_set, extra_args or None) + build_dir, all_set, extra_args or None)
def RunBinman(args): """Main entry point to binman once arguments are parsed @@ -117,7 +117,7 @@ def RunBinman(args):
if args.cmd == 'test': if args.test_coverage: - RunTestCoverage(args.toolpath) + RunTestCoverage(args.toolpath, args.build_dir) else: ret_code = RunTests(args.debug, args.verbosity, args.processes, args.test_preserve_dirs, args.tests, @@ -141,8 +141,12 @@ def RunBinman(args): return ret_code
-if __name__ == "__main__": +def start_binman(): args = cmdline.ParseArgs(sys.argv[1:])
ret_code = RunBinman(args) sys.exit(ret_code) + + +if __name__ == "__main__": + start_binman()

Put this code into a function so it is easy for it be run when packaged.
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v2: - Add patch to split out the main code into a function
tools/binman/main.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-)
Applied to u-boot-dm/next, thanks!

It doesn't make much sense to expose tests when dtoc is running outside of the U-Boot git checkout. Hide the option in this case.
Fix a long line while we are here.
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v2: - Add a patch to hide the test options unless test code is available
tools/binman/cmdline.py | 34 +++++++++++++++++++++------------- 1 file changed, 21 insertions(+), 13 deletions(-)
diff --git a/tools/binman/cmdline.py b/tools/binman/cmdline.py index 986d6f1a315..ef6a05dac15 100644 --- a/tools/binman/cmdline.py +++ b/tools/binman/cmdline.py @@ -8,6 +8,11 @@ import argparse from argparse import ArgumentParser from binman import state +import os +import pathlib + +BINMAN_DIR = pathlib.Path(__file__).parent +HAS_TESTS = (BINMAN_DIR / "ftest.py").exists()
def make_extract_parser(subparsers): """make_extract_parser: Make a subparser for the 'extract' command @@ -163,23 +168,26 @@ controlled by a description in the board device tree.''' replace_parser.add_argument('paths', type=str, nargs='*', help='Paths within file to replace (wildcard)')
- test_parser = subparsers.add_parser('test', help='Run tests') - test_parser.add_argument('-P', '--processes', type=int, - help='set number of processes to use for running tests') - test_parser.add_argument('-T', '--test-coverage', action='store_true', - default=False, help='run tests and check for 100%% coverage') - test_parser.add_argument('-X', '--test-preserve-dirs', action='store_true', - help='Preserve and display test-created input directories; also ' - 'preserve the output directory if a single test is run (pass test ' - 'name at the end of the command line') - test_parser.add_argument('tests', nargs='*', - help='Test names to run (omit for all)') + if HAS_TESTS: + test_parser = subparsers.add_parser('test', help='Run tests') + test_parser.add_argument('-P', '--processes', type=int, + help='set number of processes to use for running tests') + test_parser.add_argument('-T', '--test-coverage', action='store_true', + default=False, help='run tests and check for 100%% coverage') + test_parser.add_argument( + '-X', '--test-preserve-dirs', action='store_true', + help='Preserve and display test-created input directories; also ' + 'preserve the output directory if a single test is run (pass ' + 'test name at the end of the command line') + test_parser.add_argument('tests', nargs='*', + help='Test names to run (omit for all)')
tool_parser = subparsers.add_parser('tool', help='Check bintools') tool_parser.add_argument('-l', '--list', action='store_true', help='List all known bintools') - tool_parser.add_argument('-f', '--fetch', action='store_true', - help='fetch a bintool from a known location (or: all/missing)') + tool_parser.add_argument( + '-f', '--fetch', action='store_true', + help='fetch a bintool from a known location (or: all/missing)') tool_parser.add_argument('bintools', type=str, nargs='*')
return parser.parse_args(argv)

It doesn't make much sense to expose tests when dtoc is running outside of the U-Boot git checkout. Hide the option in this case.
Fix a long line while we are here.
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v2: - Add a patch to hide the test options unless test code is available
tools/binman/cmdline.py | 34 +++++++++++++++++++++------------- 1 file changed, 21 insertions(+), 13 deletions(-)
Applied to u-boot-dm/next, thanks!

Use this function so that the help can be found even when binman is running from a package.
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v2: - Add new patch to use importlib to find the help
tools/binman/control.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/tools/binman/control.py b/tools/binman/control.py index 3e27b72f881..e7f81b9deb5 100644 --- a/tools/binman/control.py +++ b/tools/binman/control.py @@ -7,6 +7,7 @@
from collections import OrderedDict import glob +import importlib.resources import os import pkg_resources import re @@ -641,9 +642,8 @@ def Binman(args): global state
if args.full_help: - tools.print_full_help( - os.path.join(os.path.dirname(os.path.realpath(sys.argv[0])), 'README.rst') - ) + with importlib.resources.path('binman', 'README.rst') as readme: + tools.print_full_help(str(readme)) return 0
# Put these here so that we can import this module without libfdt

Use this function so that the help can be found even when binman is running from a package.
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v2: - Add new patch to use importlib to find the help
tools/binman/control.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
Applied to u-boot-dm/next, thanks!

Create the necessary files to build this new package.
It is not actually clear whether this is useful, since buildman has no purpose outside U-Boot.
Move the main program into a function so that it can easily be called by the PyPi-created script.
Signed-off-by: Simon Glass sjg@chromium.org ---
(no changes since v1)
Makefile | 1 + tools/binman/pyproject.toml | 29 +++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+) create mode 100644 tools/binman/pyproject.toml
diff --git a/Makefile b/Makefile index 3951edabce1..27bdbec887b 100644 --- a/Makefile +++ b/Makefile @@ -2285,6 +2285,7 @@ _pip: scripts/make_pip.sh patman ${PIP_ARGS} scripts/make_pip.sh buildman ${PIP_ARGS} scripts/make_pip.sh dtoc ${PIP_ARGS} + scripts/make_pip.sh binman ${PIP_ARGS}
help: @echo 'Cleaning targets:' diff --git a/tools/binman/pyproject.toml b/tools/binman/pyproject.toml new file mode 100644 index 00000000000..b4b54fbaee6 --- /dev/null +++ b/tools/binman/pyproject.toml @@ -0,0 +1,29 @@ +[build-system] +requires = ["setuptools>=61.0"] +build-backend = "setuptools.build_meta" + +[project] +name = "binary-manager" +version = "0.0.2" +authors = [ + { name="Simon Glass", email="sjg@chromium.org" }, +] +dependencies = ["pylibfdt", "u_boot_pylib", "dtoc"] +description = "Binman firmware-packaging tool" +readme = "README.rst" +requires-python = ">=3.7" +classifiers = [ + "Programming Language :: Python :: 3", + "License :: OSI Approved :: GNU General Public License v2 or later (GPLv2+)", + "Operating System :: OS Independent", +] + +[project.urls] +"Homepage" = "https://u-boot.readthedocs.io/en/latest/develop/package/index.html" +"Bug Tracker" = "https://source.denx.de/groups/u-boot/-/issues" + +[project.scripts] +binman = "binman.main:start_binman" + +[tool.setuptools.package-data] +patman = ["*.rst"]

Create the necessary files to build this new package.
It is not actually clear whether this is useful, since buildman has no purpose outside U-Boot.
Move the main program into a function so that it can easily be called by the PyPi-created script.
Signed-off-by: Simon Glass sjg@chromium.org ---
(no changes since v1)
Makefile | 1 + tools/binman/pyproject.toml | 29 +++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+) create mode 100644 tools/binman/pyproject.toml
Applied to u-boot-dm/next, thanks!

This allows tests to run in parallel and speeds up some tests markedly, particularly with binman. Add it to the requirements.
Signed-off-by: Simon Glass sjg@chromium.org ---
(no changes since v1)
test/py/requirements.txt | 1 + 1 file changed, 1 insertion(+)
diff --git a/test/py/requirements.txt b/test/py/requirements.txt index fae8b59caf4..e241780f923 100644 --- a/test/py/requirements.txt +++ b/test/py/requirements.txt @@ -1,5 +1,6 @@ atomicwrites==1.4.1 attrs==19.3.0 +concurrencytest==0.1.2 coverage==4.5.4 extras==1.0.0 filelock==3.0.12

This allows tests to run in parallel and speeds up some tests markedly, particularly with binman. Add it to the requirements.
Signed-off-by: Simon Glass sjg@chromium.org ---
(no changes since v1)
test/py/requirements.txt | 1 + 1 file changed, 1 insertion(+)
Applied to u-boot-dm/next, thanks!

These can be installed with 'pip' now. Add the details for those who are interested.
Signed-off-by: Simon Glass sjg@chromium.org ---
(no changes since v1)
tools/binman/binman.rst | 13 +++++++++++++ tools/patman/patman.rst | 12 ++++++++++++ 2 files changed, 25 insertions(+)
diff --git a/tools/binman/binman.rst b/tools/binman/binman.rst index 2bcb7d3886f..61a5d8ab5a9 100644 --- a/tools/binman/binman.rst +++ b/tools/binman/binman.rst @@ -95,6 +95,19 @@ Binman uses the following terms: - binary - an input binary that goes into the image
+Installation +------------ + +You can install binman using:: + + pip install binary-manager + +The name is chosen since binman conflicts with an existing package. + +If you are using binman within the U-Boot tree, it may be easiest to add a +symlink from your local `~/.bin` directory to `/path/to/tools/binman/binman`. + + Relationship to FIT -------------------
diff --git a/tools/patman/patman.rst b/tools/patman/patman.rst index 6113962fb4f..038b651ee87 100644 --- a/tools/patman/patman.rst +++ b/tools/patman/patman.rst @@ -41,6 +41,18 @@ In Linux and U-Boot this will also call get_maintainer.pl on each of your patches automatically (unless you use -m to disable this).
+Installation +------------ + +You can install patman using:: + + pip install patch-manager + +The name is chosen since patman conflicts with an existing package. + +If you are using patman within the U-Boot tree, it may be easiest to add a +symlink from your local `~/.bin` directory to `/path/to/tools/patman/patman`. + How to use this tool --------------------

These can be installed with 'pip' now. Add the details for those who are interested.
Signed-off-by: Simon Glass sjg@chromium.org ---
(no changes since v1)
tools/binman/binman.rst | 13 +++++++++++++ tools/patman/patman.rst | 12 ++++++++++++ 2 files changed, 25 insertions(+)
Applied to u-boot-dm/next, thanks!

Add a simple check that the PyPi packages can be built.
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v2: - Update the cover letter
.azure-pipelines.yml | 10 ++++++++++ .gitlab-ci.yml | 6 ++++++ 2 files changed, 16 insertions(+)
diff --git a/.azure-pipelines.yml b/.azure-pipelines.yml index 8327edf87aa..6cd93f7f4d2 100644 --- a/.azure-pipelines.yml +++ b/.azure-pipelines.yml @@ -225,6 +225,16 @@ stages: # have no matches. - script: git grep u-boot,dm- -- '*.dts*' && exit 1 || exit 0
+ - job: check_packing_of_python_tools + displayName: 'Check we can package the Python tools' + pool: + vmImage: $(ubuntu_vm) + container: + image: $(ci_runner_image) + options: $(container_option) + steps: + - script: make pip + - stage: test_py jobs: - job: test_py diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index c3ceca2974d..bc64e221efd 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -244,6 +244,12 @@ Check for pre-schema tags: # have no matches. - git grep u-boot,dm- -- '*.dts*' && exit 1 || exit 0
+# Check we can package the Python tools +Check packing of Python tools: + stage: testsuites + script: + - make pip + # Test sandbox with test.py sandbox test.py: variables:

Add a simple check that the PyPi packages can be built.
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v2: - Update the cover letter
.azure-pipelines.yml | 10 ++++++++++ .gitlab-ci.yml | 6 ++++++ 2 files changed, 16 insertions(+)
Applied to u-boot-dm/next, thanks!
participants (1)
-
Simon Glass