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 # List of paths to use when looking for an input file
34 def PrepareOutputDir(dirname, preserve=False):
35 """Select an output directory, ensuring it exists.
37 This either creates a temporary directory or checks that the one supplied
38 by the user is valid. For a temporary directory, it makes a note to
39 remove it later if required.
42 dirname: a string, name of the output directory to use to store
43 intermediate and output files. If is None - create a temporary
45 preserve: a Boolean. If outdir above is None and preserve is False, the
46 created temporary directory will be destroyed on exit.
49 OSError: If it cannot create the output directory.
51 global outdir, preserve_outdir
53 preserve_outdir = dirname or preserve
56 if not os.path.isdir(outdir):
59 except OSError as err:
60 raise CmdError("Cannot make output directory '%s': '%s'" %
61 (outdir, err.strerror))
62 tout.Debug("Using output directory '%s'" % outdir)
64 outdir = tempfile.mkdtemp(prefix='binman.')
65 tout.Debug("Using temporary directory '%s'" % outdir)
67 def _RemoveOutputDir():
71 tout.Debug("Deleted temporary directory '%s'" % outdir)
74 def FinaliseOutputDir():
75 global outdir, preserve_outdir
77 """Tidy up: delete output directory if temporary and not preserved."""
78 if outdir and not preserve_outdir:
81 def GetOutputFilename(fname):
82 """Return a filename within the output directory.
85 fname: Filename to use for new file
88 The full path of the filename, within the output directory
90 return os.path.join(outdir, fname)
92 def _FinaliseForTest():
93 """Remove the output directory (for use by tests)"""
99 def SetInputDirs(dirname):
100 """Add a list of input directories, where input files are kept.
103 dirname: a list of paths to input directories to use for obtaining
104 files needed by binman to place in the image.
109 tout.Debug("Using input directories %s" % indir)
111 def GetInputFilename(fname):
112 """Return a filename for use as input.
115 fname: Filename to use for new file
118 The full path of the filename, within the input directory
122 for dirname in indir:
123 pathname = os.path.join(dirname, fname)
124 if os.path.exists(pathname):
127 raise ValueError("Filename '%s' not found in input path (%s) (cwd='%s')" %
128 (fname, ','.join(indir), os.getcwd()))
130 def GetInputFilenameGlob(pattern):
131 """Return a list of filenames for use as input.
134 pattern: Filename pattern to search for
137 A list of matching files in all input directories
140 return glob.glob(fname)
142 for dirname in indir:
143 pathname = os.path.join(dirname, pattern)
144 files += glob.glob(pathname)
147 def Align(pos, align):
150 pos = (pos + mask) & ~mask
153 def NotPowerOfTwo(num):
154 return num and (num & (num - 1))
156 def PathHasFile(fname):
157 """Check if a given filename is in the PATH
160 fname: Filename to check
163 True if found, False if not
165 for dir in os.environ['PATH'].split(':'):
166 if os.path.exists(os.path.join(dir, fname)):
170 def Run(name, *args):
172 return command.Run(name, *args, cwd=outdir, capture=True)
174 if not PathHasFile(name):
175 msg = "Plesae install tool '%s'" % name
176 package = packages.get(name)
178 msg += " (e.g. from package '%s')" % package
179 raise ValueError(msg)
183 """Resolve a file path to an absolute path.
185 If fname starts with ##/ and chroot is available, ##/ gets replaced with
186 the chroot path. If chroot is not available, this file name can not be
187 resolved, `None' is returned.
189 If fname is not prepended with the above prefix, and is not an existing
190 file, the actual file name is retrieved from the passed in string and the
191 search_paths directories (if any) are searched to for the file. If found -
192 the path to the found file is returned, `None' is returned otherwise.
195 fname: a string, the path to resolve.
198 Absolute path to the file or None if not found.
200 if fname.startswith('##/'):
202 fname = os.path.join(chroot_path, fname[3:])
206 # Search for a pathname that exists, and return it if found
207 if fname and not os.path.exists(fname):
208 for path in search_paths:
209 pathname = os.path.join(path, os.path.basename(fname))
210 if os.path.exists(pathname):
213 # If not found, just return the standard, unchanged path
217 """Read and return the contents of a file.
220 fname: path to filename to read, where ## signifiies the chroot.
223 data read from file, as a string.
225 with open(Filename(fname), 'rb') as fd:
227 #self._out.Info("Read file '%s' size %d (%#0x)" %
228 #(fname, len(data), len(data)))
231 def WriteFile(fname, data):
232 """Write data into a file.
235 fname: path to filename to write
236 data: data to write to file, as a string
238 #self._out.Info("Write file '%s' size %d (%#0x)" %
239 #(fname, len(data), len(data)))
240 with open(Filename(fname), 'wb') as fd: