1eb8dc403SDave Cobbley#!/usr/bin/env python3
2eb8dc403SDave Cobbley
3eb8dc403SDave Cobbley# Query which tasks will be restored from sstate
4eb8dc403SDave Cobbley#
5eb8dc403SDave Cobbley# Copyright 2016 Intel Corporation
6eb8dc403SDave Cobbley# Authored-by:  Paul Eggleton <paul.eggleton@intel.com>
7eb8dc403SDave Cobbley#
8c342db35SBrad Bishop# SPDX-License-Identifier: GPL-2.0-only
9eb8dc403SDave Cobbley#
10eb8dc403SDave Cobbley
11eb8dc403SDave Cobbleyimport sys
12eb8dc403SDave Cobbleyimport os
13eb8dc403SDave Cobbleyimport subprocess
14eb8dc403SDave Cobbleyimport tempfile
15eb8dc403SDave Cobbleyimport shutil
16eb8dc403SDave Cobbleyimport re
17eb8dc403SDave Cobbley
18eb8dc403SDave Cobbleyscripts_path = os.path.dirname(os.path.realpath(__file__))
19eb8dc403SDave Cobbleylib_path = scripts_path + '/lib'
20eb8dc403SDave Cobbleysys.path = sys.path + [lib_path]
21eb8dc403SDave Cobbleyimport scriptpath
22eb8dc403SDave Cobbleyscriptpath.add_bitbake_lib_path()
23eb8dc403SDave Cobbleyimport argparse_oe
24eb8dc403SDave Cobbley
25eb8dc403SDave Cobbley
26eb8dc403SDave Cobbleydef translate_virtualfns(tasks):
27eb8dc403SDave Cobbley    import bb.tinfoil
28eb8dc403SDave Cobbley    tinfoil = bb.tinfoil.Tinfoil()
29eb8dc403SDave Cobbley    try:
30eb8dc403SDave Cobbley        tinfoil.prepare(False)
31eb8dc403SDave Cobbley
32eb8dc403SDave Cobbley        recipecaches = tinfoil.cooker.recipecaches
33eb8dc403SDave Cobbley        outtasks = []
34eb8dc403SDave Cobbley        for task in tasks:
35eb8dc403SDave Cobbley            (mc, fn, taskname) = bb.runqueue.split_tid(task)
36eb8dc403SDave Cobbley            if taskname.endswith('_setscene'):
37eb8dc403SDave Cobbley                taskname = taskname[:-9]
38eb8dc403SDave Cobbley            outtasks.append('%s:%s' % (recipecaches[mc].pkg_fn[fn], taskname))
39eb8dc403SDave Cobbley    finally:
40eb8dc403SDave Cobbley        tinfoil.shutdown()
41eb8dc403SDave Cobbley    return outtasks
42eb8dc403SDave Cobbley
43eb8dc403SDave Cobbley
44eb8dc403SDave Cobbleydef check(args):
45eb8dc403SDave Cobbley    tmpdir = tempfile.mkdtemp(prefix='oe-check-sstate-')
46eb8dc403SDave Cobbley    try:
47eb8dc403SDave Cobbley        env = os.environ.copy()
48eb8dc403SDave Cobbley        if not args.same_tmpdir:
497e0e3c0cSAndrew Geissler            env['BB_ENV_PASSTHROUGH_ADDITIONS'] = env.get('BB_ENV_PASSTHROUGH_ADDITIONS', '') + ' TMPDIR:forcevariable'
50213cb269SPatrick Williams            env['TMPDIR:forcevariable'] = tmpdir
51eb8dc403SDave Cobbley
52eb8dc403SDave Cobbley        try:
532390b1b6SPatrick Williams            cmd = ['bitbake', '--dry-run', '--runall=build'] + args.target
542390b1b6SPatrick Williams            output = subprocess.check_output(cmd, stderr=subprocess.STDOUT, env=env)
55eb8dc403SDave Cobbley
56*73bd93f1SPatrick Williams            task_re = re.compile(r'NOTE: Running setscene task [0-9]+ of [0-9]+ \(([^)]+)\)')
57eb8dc403SDave Cobbley            tasks = []
58eb8dc403SDave Cobbley            for line in output.decode('utf-8').splitlines():
59eb8dc403SDave Cobbley                res = task_re.match(line)
60eb8dc403SDave Cobbley                if res:
61eb8dc403SDave Cobbley                    tasks.append(res.group(1))
62eb8dc403SDave Cobbley            outtasks = translate_virtualfns(tasks)
63eb8dc403SDave Cobbley        except subprocess.CalledProcessError as e:
64eb8dc403SDave Cobbley            print('ERROR: bitbake failed:\n%s' % e.output.decode('utf-8'))
65eb8dc403SDave Cobbley            return e.returncode
66eb8dc403SDave Cobbley    finally:
67eb8dc403SDave Cobbley        shutil.rmtree(tmpdir)
68eb8dc403SDave Cobbley
69eb8dc403SDave Cobbley    if args.log:
70eb8dc403SDave Cobbley        with open(args.log, 'wb') as f:
71eb8dc403SDave Cobbley            f.write(output)
72eb8dc403SDave Cobbley
73eb8dc403SDave Cobbley    if args.outfile:
74eb8dc403SDave Cobbley        with open(args.outfile, 'w') as f:
75eb8dc403SDave Cobbley            for task in outtasks:
76eb8dc403SDave Cobbley                f.write('%s\n' % task)
77eb8dc403SDave Cobbley    else:
78eb8dc403SDave Cobbley        for task in outtasks:
79eb8dc403SDave Cobbley            print(task)
80eb8dc403SDave Cobbley
81eb8dc403SDave Cobbley    return 0
82eb8dc403SDave Cobbley
83eb8dc403SDave Cobbley
84eb8dc403SDave Cobbleydef main():
85eb8dc403SDave Cobbley    parser = argparse_oe.ArgumentParser(description='OpenEmbedded sstate check tool. Does a dry-run to check restoring the specified targets from shared state, and lists the tasks that would be restored. Set BB_SETSCENE_ENFORCE=1 in the environment if you wish to ensure real tasks are disallowed.')
86eb8dc403SDave Cobbley
87eb8dc403SDave Cobbley    parser.add_argument('target', nargs='+', help='Target to check')
88eb8dc403SDave Cobbley    parser.add_argument('-o', '--outfile', help='Write list to a file instead of stdout')
89eb8dc403SDave Cobbley    parser.add_argument('-l', '--log', help='Write full log to a file')
90eb8dc403SDave Cobbley    parser.add_argument('-s', '--same-tmpdir', action='store_true', help='Use same TMPDIR for check (list will then be dependent on what tasks have executed previously)')
91eb8dc403SDave Cobbley
92eb8dc403SDave Cobbley    parser.set_defaults(func=check)
93eb8dc403SDave Cobbley
94eb8dc403SDave Cobbley    args = parser.parse_args()
95eb8dc403SDave Cobbley
96eb8dc403SDave Cobbley    ret = args.func(args)
97eb8dc403SDave Cobbley    return ret
98eb8dc403SDave Cobbley
99eb8dc403SDave Cobbley
100eb8dc403SDave Cobbleyif __name__ == "__main__":
101eb8dc403SDave Cobbley    try:
102eb8dc403SDave Cobbley        ret = main()
103eb8dc403SDave Cobbley    except Exception:
104eb8dc403SDave Cobbley        ret = 1
105eb8dc403SDave Cobbley        import traceback
106eb8dc403SDave Cobbley        traceback.print_exc()
107eb8dc403SDave Cobbley    sys.exit(ret)
108