Re: [PATCH 05/17] binman: Add a way to obtain the version

2021-12-02 Thread Simon Glass
Add a -V option which shows the version number of binman. For now this
just uses a local 'version' file. Once the tool is packaged in some way
we can figure out an approach that suits.

Signed-off-by: Simon Glass 
---

 tools/binman/cmdline.py | 29 +
 tools/binman/ftest.py   | 20 
 tools/binman/state.py   | 18 ++
 3 files changed, 67 insertions(+)

Applied to u-boot-dm/next, thanks!


[PATCH 05/17] binman: Add a way to obtain the version

2021-11-23 Thread Simon Glass
Add a -V option which shows the version number of binman. For now this
just uses a local 'version' file. Once the tool is packaged in some way
we can figure out an approach that suits.

Signed-off-by: Simon Glass 
---

 tools/binman/cmdline.py | 29 +
 tools/binman/ftest.py   | 20 
 tools/binman/state.py   | 18 ++
 3 files changed, 67 insertions(+)

diff --git a/tools/binman/cmdline.py b/tools/binman/cmdline.py
index 14ec95c25be..2229316f10e 100644
--- a/tools/binman/cmdline.py
+++ b/tools/binman/cmdline.py
@@ -5,7 +5,9 @@
 
 """Command-line parser for binman"""
 
+import argparse
 from argparse import ArgumentParser
+import state
 
 def make_extract_parser(subparsers):
 """make_extract_parser: Make a subparser for the 'extract' command
@@ -26,6 +28,32 @@ def make_extract_parser(subparsers):
 extract_parser.add_argument('-U', '--uncompressed', action='store_true',
 help='Output raw uncompressed data for compressed entries')
 
+
+#pylint: disable=R0903
+class BinmanVersion(argparse.Action):
+"""Handles the -V option to binman
+
+This reads the version information from a file called 'version' in the same
+directory as this file.
+
+If not present it assumes this is running from the U-Boot tree and collects
+the version from the Makefile.
+
+The format of the version information is three VAR = VALUE lines, for
+example:
+
+VERSION = 2022
+PATCHLEVEL = 01
+EXTRAVERSION = -rc2
+"""
+def __init__(self, nargs=0, **kwargs):
+super().__init__(nargs=nargs, **kwargs)
+
+def __call__(self, parser, namespace, values, option_string=None):
+parser._print_message(f'Binman {state.GetVersion()}\n')
+parser.exit()
+
+
 def ParseArgs(argv):
 """Parse the binman command-line arguments
 
@@ -59,6 +87,7 @@ controlled by a description in the board device tree.'''
 parser.add_argument('-v', '--verbosity', default=1,
 type=int, help='Control verbosity: 0=silent, 1=warnings, 2=notices, '
 '3=info, 4=detail, 5=debug')
+parser.add_argument('-V', '--version', nargs=0, action=BinmanVersion)
 
 subparsers = parser.add_subparsers(dest='cmd')
 subparsers.required = True
diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py
index 6be003786e8..6a36e8f3158 100644
--- a/tools/binman/ftest.py
+++ b/tools/binman/ftest.py
@@ -4661,6 +4661,26 @@ class TestFunctional(unittest.TestCase):
 str(e.exception),
 "Not enough space in '.*u_boot_binman_embed_sm' for data length.*")
 
+def testVersion(self):
+"""Test we can get the binman version"""
+version = '(unreleased)'
+self.assertEqual(version, state.GetVersion(self._indir))
+
+with self.assertRaises(SystemExit):
+with test_util.capture_sys_output() as (_, stderr):
+self._DoBinman('-V')
+self.assertEqual('Binman %s\n' % version, stderr.getvalue())
+
+# Try running the tool too, just to be safe
+result = self._RunBinman('-V')
+self.assertEqual('Binman %s\n' % version, result.stderr)
+
+# Set up a version file to make sure that works
+version = 'v2025.01-rc2'
+tools.WriteFile(os.path.join(self._indir, 'version'), version,
+binary=False)
+self.assertEqual(version, state.GetVersion(self._indir))
+
 
 if __name__ == "__main__":
 unittest.main()
diff --git a/tools/binman/state.py b/tools/binman/state.py
index 9e5b8a39310..af0a65e8418 100644
--- a/tools/binman/state.py
+++ b/tools/binman/state.py
@@ -16,6 +16,8 @@ import os
 from patman import tools
 from patman import tout
 
+OUR_PATH = os.path.dirname(os.path.realpath(__file__))
+
 # Map an dtb etype to its expected filename
 DTB_TYPE_FNAME = {
 'u-boot-spl-dtb': 'spl/u-boot-spl.dtb',
@@ -515,3 +517,19 @@ def TimingShow():
 
 for name, seconds in duration.items():
 print('%10s: %10.1fms' % (name, seconds * 1000))
+
+def GetVersion(path=OUR_PATH):
+"""Get the version string for binman
+
+Args:
+path: Path to 'version' file
+
+Returns:
+str: String version, e.g. 'v2021.10'
+"""
+version_fname = os.path.join(path, 'version')
+if os.path.exists(version_fname):
+version = tools.ReadFile(version_fname, binary=False)
+else:
+version = '(unreleased)'
+return version
-- 
2.34.0.rc2.393.gf8c9666880-goog