blob: 92b601c7e8473ae239aae879181757e8c07cacfe [file] [log] [blame]
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001# Script utility functions
2#
3# Copyright (C) 2014 Intel Corporation
4#
5# This program is free software; you can redistribute it and/or modify
6# it under the terms of the GNU General Public License version 2 as
7# published by the Free Software Foundation.
8#
9# This program is distributed in the hope that it will be useful,
10# but WITHOUT ANY WARRANTY; without even the implied warranty of
11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12# GNU General Public License for more details.
13#
14# You should have received a copy of the GNU General Public License along
15# with this program; if not, write to the Free Software Foundation, Inc.,
16# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17
18import sys
19import os
20import logging
21import glob
Patrick Williamsd8c66bc2016-06-20 12:57:21 -050022import argparse
23import subprocess
Brad Bishop6e60e8b2018-02-01 10:27:11 -050024import tempfile
25import shutil
Patrick Williamsc124f4f2015-09-15 14:41:29 -050026
Brad Bishop6e60e8b2018-02-01 10:27:11 -050027def logger_create(name, stream=None):
Patrick Williamsc124f4f2015-09-15 14:41:29 -050028 logger = logging.getLogger(name)
Brad Bishop6e60e8b2018-02-01 10:27:11 -050029 loggerhandler = logging.StreamHandler(stream=stream)
Patrick Williamsc124f4f2015-09-15 14:41:29 -050030 loggerhandler.setFormatter(logging.Formatter("%(levelname)s: %(message)s"))
31 logger.addHandler(loggerhandler)
32 logger.setLevel(logging.INFO)
33 return logger
34
35def logger_setup_color(logger, color='auto'):
36 from bb.msg import BBLogFormatter
37 console = logging.StreamHandler(sys.stdout)
38 formatter = BBLogFormatter("%(levelname)s: %(message)s")
39 console.setFormatter(formatter)
40 logger.handlers = [console]
41 if color == 'always' or (color=='auto' and console.stream.isatty()):
42 formatter.enable_color()
43
44
45def load_plugins(logger, plugins, pluginpath):
46 import imp
47
48 def load_plugin(name):
49 logger.debug('Loading plugin %s' % name)
50 fp, pathname, description = imp.find_module(name, [pluginpath])
51 try:
52 return imp.load_module(name, fp, pathname, description)
53 finally:
54 if fp:
55 fp.close()
56
Brad Bishop6e60e8b2018-02-01 10:27:11 -050057 def plugin_name(filename):
58 return os.path.splitext(os.path.basename(filename))[0]
59
60 known_plugins = [plugin_name(p.__name__) for p in plugins]
Patrick Williamsc124f4f2015-09-15 14:41:29 -050061 logger.debug('Loading plugins from %s...' % pluginpath)
62 for fn in glob.glob(os.path.join(pluginpath, '*.py')):
Brad Bishop6e60e8b2018-02-01 10:27:11 -050063 name = plugin_name(fn)
64 if name != '__init__' and name not in known_plugins:
Patrick Williamsc124f4f2015-09-15 14:41:29 -050065 plugin = load_plugin(name)
66 if hasattr(plugin, 'plugin_init'):
67 plugin.plugin_init(plugins)
68 plugins.append(plugin)
69
70def git_convert_standalone_clone(repodir):
71 """If specified directory is a git repository, ensure it's a standalone clone"""
72 import bb.process
73 if os.path.exists(os.path.join(repodir, '.git')):
74 alternatesfile = os.path.join(repodir, '.git', 'objects', 'info', 'alternates')
75 if os.path.exists(alternatesfile):
76 # This will have been cloned with -s, so we need to convert it so none
77 # of the contents is shared
78 bb.process.run('git repack -a', cwd=repodir)
79 os.remove(alternatesfile)
80
81def fetch_uri(d, uri, destdir, srcrev=None):
82 """Fetch a URI to a local directory"""
Brad Bishop6e60e8b2018-02-01 10:27:11 -050083 import bb
84 tmpparent = d.getVar('BASE_WORKDIR')
85 bb.utils.mkdirhier(tmpparent)
86 tmpworkdir = tempfile.mkdtemp(dir=tmpparent)
Patrick Williamsc124f4f2015-09-15 14:41:29 -050087 try:
Brad Bishop6e60e8b2018-02-01 10:27:11 -050088 bb.utils.mkdirhier(destdir)
89 localdata = bb.data.createCopy(d)
90
91 # Set some values to allow extend_recipe_sysroot to work here we're we are not running from a task
92 localdata.setVar('WORKDIR', tmpworkdir)
93 localdata.setVar('BB_RUNTASK', 'do_fetch')
94 localdata.setVar('PN', 'dummy')
95 localdata.setVar('BB_LIMITEDDEPS', '1')
96 bb.build.exec_func("extend_recipe_sysroot", localdata)
97
98 # Set some values for the benefit of the fetcher code
99 localdata.setVar('BB_STRICT_CHECKSUM', '')
100 localdata.setVar('SRCREV', srcrev)
101 ret = (None, None)
102 olddir = os.getcwd()
103 try:
104 fetcher = bb.fetch2.Fetch([uri], localdata)
105 for u in fetcher.ud:
106 ud = fetcher.ud[u]
107 ud.ignore_checksums = True
108 fetcher.download()
109 for u in fetcher.ud:
110 ud = fetcher.ud[u]
111 if ud.localpath.rstrip(os.sep) == localdata.getVar('DL_DIR').rstrip(os.sep):
112 raise Exception('Local path is download directory - please check that the URI "%s" is correct' % uri)
113 fetcher.unpack(destdir)
114 for u in fetcher.ud:
115 ud = fetcher.ud[u]
116 if ud.method.recommends_checksum(ud):
117 md5value = bb.utils.md5_file(ud.localpath)
118 sha256value = bb.utils.sha256_file(ud.localpath)
119 ret = (md5value, sha256value)
120 finally:
121 os.chdir(olddir)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500122 finally:
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500123 shutil.rmtree(tmpworkdir)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500124 return ret
125
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500126def run_editor(fn):
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600127 if isinstance(fn, str):
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500128 params = '"%s"' % fn
129 else:
130 params = ''
131 for fnitem in fn:
132 params += ' "%s"' % fnitem
133
134 editor = os.getenv('VISUAL', os.getenv('EDITOR', 'vi'))
135 try:
136 return subprocess.check_call('%s %s' % (editor, params), shell=True)
137 except OSError as exc:
138 logger.error("Execution of editor '%s' failed: %s", editor, exc)
139 return 1
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600140
141def is_src_url(param):
142 """
143 Check if a parameter is a URL and return True if so
144 NOTE: be careful about changing this as it will influence how devtool/recipetool command line handling works
145 """
146 if not param:
147 return False
148 elif '://' in param:
149 return True
150 elif param.startswith('git@') or ('@' in param and param.endswith('.git')):
151 return True
152 return False