1 # SPDX-License-Identifier: GPL-2.0+
3 # Copyright (c) 2016 Google, Inc
14 # Output directly (generally this is temporary)
17 # True to keep the output directory around after exiting
18 preserve_outdir = False
20 # Path to the Chrome OS chroot, if we know it
23 # Search paths to use for Filename(), used to find files
26 # Tools and the packages that contain them, on debian
31 def PrepareOutputDir(dirname, preserve=False):
32 """Select an output directory, ensuring it exists.
34 This either creates a temporary directory or checks that the one supplied
35 by the user is valid. For a temporary directory, it makes a note to
36 remove it later if required.
39 dirname: a string, name of the output directory to use to store
40 intermediate and output files. If is None - create a temporary
42 preserve: a Boolean. If outdir above is None and preserve is False, the
43 created temporary directory will be destroyed on exit.
46 OSError: If it cannot create the output directory.
48 global outdir, preserve_outdir
50 preserve_outdir = dirname or preserve
53 if not os.path.isdir(outdir):
56 except OSError as err:
57 raise CmdError("Cannot make output directory '%s': '%s'" %
58 (outdir, err.strerror))
59 tout.Debug("Using output directory '%s'" % outdir)
61 outdir = tempfile.mkdtemp(prefix='binman.')
62 tout.Debug("Using temporary directory '%s'" % outdir)
64 def _RemoveOutputDir():
68 tout.Debug("Deleted temporary directory '%s'" % outdir)
71 def FinaliseOutputDir():
72 global outdir, preserve_outdir
74 """Tidy up: delete output directory if temporary and not preserved."""
75 if outdir and not preserve_outdir:
78 def GetOutputFilename(fname):
79 """Return a filename within the output directory.
82 fname: Filename to use for new file
85 The full path of the filename, within the output directory
87 return os.path.join(outdir, fname)
89 def _FinaliseForTest():
90 """Remove the output directory (for use by tests)"""
96 def SetInputDirs(dirname):
97 """Add a list of input directories, where input files are kept.
100 dirname: a list of paths to input directories to use for obtaining
101 files needed by binman to place in the image.
106 tout.Debug("Using input directories %s" % indir)
108 def GetInputFilename(fname):
109 """Return a filename for use as input.
112 fname: Filename to use for new file
115 The full path of the filename, within the input directory
119 for dirname in indir:
120 pathname = os.path.join(dirname, fname)
121 if os.path.exists(pathname):
124 raise ValueError("Filename '%s' not found in input path (%s) (cwd='%s')" %
125 (fname, ','.join(indir), os.getcwd()))
127 def GetInputFilenameGlob(pattern):
128 """Return a list of filenames for use as input.
131 pattern: Filename pattern to search for
134 A list of matching files in all input directories
137 return glob.glob(fname)
139 for dirname in indir:
140 pathname = os.path.join(dirname, pattern)
141 files += glob.glob(pathname)
144 def Align(pos, align):
147 pos = (pos + mask) & ~mask
150 def NotPowerOfTwo(num):
151 return num and (num & (num - 1))
153 def PathHasFile(fname):
154 """Check if a given filename is in the PATH
157 fname: Filename to check
160 True if found, False if not
162 for dir in os.environ['PATH'].split(':'):
163 if os.path.exists(os.path.join(dir, fname)):
167 def Run(name, *args):
169 return command.Run(name, *args, cwd=outdir, capture=True)
171 if not PathHasFile(name):
172 msg = "Plesae install tool '%s'" % name
173 package = packages.get(name)
175 msg += " (e.g. from package '%s')" % package
176 raise ValueError(msg)
180 """Resolve a file path to an absolute path.
182 If fname starts with ##/ and chroot is available, ##/ gets replaced with
183 the chroot path. If chroot is not available, this file name can not be
184 resolved, `None' is returned.
186 If fname is not prepended with the above prefix, and is not an existing
187 file, the actual file name is retrieved from the passed in string and the
188 search_paths directories (if any) are searched to for the file. If found -
189 the path to the found file is returned, `None' is returned otherwise.
192 fname: a string, the path to resolve.
195 Absolute path to the file or None if not found.
197 if fname.startswith('##/'):
199 fname = os.path.join(chroot_path, fname[3:])
203 # Search for a pathname that exists, and return it if found
204 if fname and not os.path.exists(fname):
205 for path in search_paths:
206 pathname = os.path.join(path, os.path.basename(fname))
207 if os.path.exists(pathname):
210 # If not found, just return the standard, unchanged path
214 """Read and return the contents of a file.
217 fname: path to filename to read, where ## signifiies the chroot.
220 data read from file, as a string.
222 with open(Filename(fname), 'rb') as fd:
224 #self._out.Info("Read file '%s' size %d (%#0x)" %
225 #(fname, len(data), len(data)))
228 def WriteFile(fname, data):
229 """Write data into a file.
232 fname: path to filename to write
233 data: data to write to file, as a string
235 #self._out.Info("Write file '%s' size %d (%#0x)" %
236 #(fname, len(data), len(data)))
237 with open(Filename(fname), 'wb') as fd: