patman: Add a tools library for using temporary files
authorSimon Glass <sjg@chromium.org>
Tue, 26 Jul 2016 00:59:08 +0000 (18:59 -0600)
committerSimon Glass <sjg@chromium.org>
Mon, 19 Sep 2016 03:04:38 +0000 (21:04 -0600)
For tools which want to use input files and temporary output, it is useful
to have the handling of these dealt with in one place. Add a new library
which allows input files to be read, and output files to be written, all
based on a common directory structure.

Signed-off-by: Simon Glass <sjg@chromium.org>
tools/patman/tools.py [new file with mode: 0644]

diff --git a/tools/patman/tools.py b/tools/patman/tools.py
new file mode 100644 (file)
index 0000000..ba24853
--- /dev/null
@@ -0,0 +1,120 @@
+#
+# Copyright (c) 2016 Google, Inc
+#
+# SPDX-License-Identifier:      GPL-2.0+
+#
+
+import os
+import shutil
+import tempfile
+
+import tout
+
+outdir = None
+indirs = None
+preserve_outdir = False
+
+def PrepareOutputDir(dirname, preserve=False):
+    """Select an output directory, ensuring it exists.
+
+    This either creates a temporary directory or checks that the one supplied
+    by the user is valid. For a temporary directory, it makes a note to
+    remove it later if required.
+
+    Args:
+        dirname: a string, name of the output directory to use to store
+                intermediate and output files. If is None - create a temporary
+                directory.
+        preserve: a Boolean. If outdir above is None and preserve is False, the
+                created temporary directory will be destroyed on exit.
+
+    Raises:
+        OSError: If it cannot create the output directory.
+    """
+    global outdir, preserve_outdir
+
+    preserve_outdir = dirname or preserve
+    if dirname:
+        outdir = dirname
+        if not os.path.isdir(outdir):
+            try:
+                os.makedirs(outdir)
+            except OSError as err:
+                raise CmdError("Cannot make output directory '%s': '%s'" %
+                                (outdir, err.strerror))
+        tout.Debug("Using output directory '%s'" % outdir)
+    else:
+        outdir = tempfile.mkdtemp(prefix='binman.')
+        tout.Debug("Using temporary directory '%s'" % outdir)
+
+def _RemoveOutputDir():
+    global outdir
+
+    shutil.rmtree(outdir)
+    tout.Debug("Deleted temporary directory '%s'" % outdir)
+    outdir = None
+
+def FinaliseOutputDir():
+    global outdir, preserve_outdir
+
+    """Tidy up: delete output directory if temporary and not preserved."""
+    if outdir and not preserve_outdir:
+        _RemoveOutputDir()
+
+def GetOutputFilename(fname):
+    """Return a filename within the output directory.
+
+    Args:
+        fname: Filename to use for new file
+
+    Returns:
+        The full path of the filename, within the output directory
+    """
+    return os.path.join(outdir, fname)
+
+def _FinaliseForTest():
+    """Remove the output directory (for use by tests)"""
+    global outdir
+
+    if outdir:
+        _RemoveOutputDir()
+
+def SetInputDirs(dirname):
+    """Add a list of input directories, where input files are kept.
+
+    Args:
+        dirname: a list of paths to input directories to use for obtaining
+                files needed by binman to place in the image.
+    """
+    global indir
+
+    indir = dirname
+    tout.Debug("Using input directories %s" % indir)
+
+def GetInputFilename(fname):
+    """Return a filename for use as input.
+
+    Args:
+        fname: Filename to use for new file
+
+    Returns:
+        The full path of the filename, within the input directory
+    """
+    if not indir:
+        return fname
+    for dirname in indir:
+        pathname = os.path.join(dirname, fname)
+        if os.path.exists(pathname):
+            return pathname
+
+    raise ValueError("Filename '%s' not found in input path (%s)" %
+                     (fname, ','.join(indir)))
+
+def Align(pos, align):
+    if align:
+        mask = align - 1
+        pos = (pos + mask) & ~mask
+    return pos
+
+def NotPowerOfTwo(num):
+    return num and (num & (num - 1))