a particular tool. Some tools are built from source code, in which case you will
need to have at least the `build-essential` and `git` packages installed.
-Tools are fetched into the `~/.binman-tools` directory.
+Tools are fetched into the `~/.binman-tools` directory. This directory is
+automatically added to the toolpath so there is no need to use `--toolpath` to
+specify it. If you want to use these tools outside binman, you may want to
+add this directory to your `PATH`. For example, if you use bash, add this to
+the end of `.bashrc`::
+
+ PATH="$HOME/.binman-tools:$PATH"
+
+To select a custom directory, use the `--tooldir` option.
Bintool Documentation
=====================
Usage::
- binman [-h] [-B BUILD_DIR] [-D] [-H] [--toolpath TOOLPATH] [-T THREADS]
- [--test-section-timeout] [-v VERBOSITY] [-V]
+ binman [-h] [-B BUILD_DIR] [-D] [--tooldir TOOLDIR] [-H]
+ [--toolpath TOOLPATH] [-T THREADS] [--test-section-timeout]
+ [-v VERBOSITY] [-V]
{build,bintool-docs,entry-docs,ls,extract,replace,test,tool} ...
Binman provides the following commands:
-D, --debug
Enabling debugging (provides a full traceback on error)
+--tooldir TOOLDIR Set the directory to store tools
+
-H, --full-help
Display the README file
--toolpath TOOLPATH
- Add a path to the directories containing tools
+ Add a path to the list of directories containing tools
-T THREADS, --threads THREADS
Number of threads to use (0=single-thread). Note that -T0 is useful for
# List of bintools to regard as missing
missing_list = []
- # Directory to store tools
- tooldir = os.path.join(os.getenv('HOME'), '.binman-tools')
+ # Directory to store tools. Note that this set up by set_tool_dir() which
+ # must be called before this class is used.
+ tooldir = ''
def __init__(self, name, desc, version_regex=None, version_args='-V'):
self.name = name
obj = cls(name)
return obj
+ @classmethod
+ def set_tool_dir(cls, pathname):
+ """Set the path to use to store and find tools"""
+ cls.tooldir = pathname
+
def show(self):
"""Show a line of information about a bintool"""
if self.is_present():
if result is not True:
fname, tmpdir = result
dest = os.path.join(self.tooldir, self.name)
+ os.makedirs(self.tooldir, exist_ok=True)
print(f"- writing to '{dest}'")
shutil.move(fname, dest)
if tmpdir:
dirname = os.path.join(self._indir, 'download_dir')
os.mkdir(dirname)
fname = os.path.join(dirname, 'downloaded')
+
+ # Rely on bintool to create this directory
destdir = os.path.join(self._indir, 'dest_dir')
- os.mkdir(destdir)
+
dest_fname = os.path.join(destdir, '_testing')
self.seq = 0
def test_failed_command(self):
"""Check that running a command that does not exist returns None"""
- btool = Bintool.create('_testing')
- result = btool.run_cmd_result('fred')
+ destdir = os.path.join(self._indir, 'dest_dir')
+ os.mkdir(destdir)
+ with unittest.mock.patch.object(bintool.Bintool, 'tooldir', destdir):
+ btool = Bintool.create('_testing')
+ result = btool.run_cmd_result('fred')
self.assertIsNone(result)
import argparse
from argparse import ArgumentParser
+import os
from binman import state
def make_extract_parser(subparsers):
help='Enabling debugging (provides a full traceback on error)')
parser.add_argument('-H', '--full-help', action='store_true',
default=False, help='Display the README file')
+ parser.add_argument('--tooldir', type=str,
+ default=os.path.join(os.getenv('HOME'), '.binman-tools'),
+ help='Set the directory to store tools')
parser.add_argument('--toolpath', type=str, action='append',
- help='Add a path to the directories containing tools')
+ help='Add a path to the list of directories containing tools')
parser.add_argument('-T', '--threads', type=int,
default=None, help='Number of threads to use (0=single-thread)')
parser.add_argument('--test-section-timeout', action='store_true',
from binman.image import Image
from binman import state
+ tool_paths = []
+ if args.toolpath:
+ tool_paths += args.toolpath
+ if args.tooldir:
+ tool_paths.append(args.tooldir)
+ tools.set_tool_paths(tool_paths or None)
+ bintool.Bintool.set_tool_dir(args.tooldir)
+
if args.cmd in ['ls', 'extract', 'replace', 'tool']:
try:
tout.init(args.verbosity)
allow_resize=not args.fix_size, write_map=args.map)
if args.cmd == 'tool':
- tools.set_tool_paths(args.toolpath)
if args.list:
bintool.Bintool.list_all()
elif args.fetch:
try:
tools.set_input_dirs(args.indir)
tools.prepare_output_dir(args.outdir, args.preserve)
- tools.set_tool_paths(args.toolpath)
state.SetEntryArgs(args.entry_arg)
state.SetThreads(args.threads)
def _HandleGbbCommand(self, pipe_list):
"""Fake calls to the futility utility"""
- if pipe_list[0][0] == 'futility':
+ if 'futility' in pipe_list[0][0]:
fname = pipe_list[0][-1]
# Append our GBB data to the file, which will happen every time the
# futility command is called.
self._hash_data is False, it writes VBLOCK_DATA, else it writes a hash
of the input data (here, 'input.vblock').
"""
- if pipe_list[0][0] == 'futility':
+ if 'futility' in pipe_list[0][0]:
fname = pipe_list[0][3]
with open(fname, 'wb') as fd:
if self._hash_data:
self.assertEqual(['u-boot', 'atf-2'],
fdt_util.GetStringList(node, 'loadables'))
+ def testTooldir(self):
+ """Test that we can specify the tooldir"""
+ with test_util.capture_sys_output() as (stdout, stderr):
+ self.assertEqual(0, self._DoBinman('--tooldir', 'fred',
+ 'tool', '-l'))
+ self.assertEqual('fred', bintool.Bintool.tooldir)
+
+ # Check that the toolpath is updated correctly
+ self.assertEqual(['fred'], tools.tool_search_paths)
+
+ # Try with a few toolpaths; the tooldir should be at the end
+ with test_util.capture_sys_output() as (stdout, stderr):
+ self.assertEqual(0, self._DoBinman(
+ '--toolpath', 'mary', '--toolpath', 'anna', '--tooldir', 'fred',
+ 'tool', '-l'))
+ self.assertEqual(['mary', 'anna', 'fred'], tools.tool_search_paths)
+
if __name__ == "__main__":
unittest.main()