From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.4 required=3.0 tests=DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,HTML_MESSAGE,INCLUDES_PATCH,MAILING_LIST_MULTI, SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id F0CCDC43331 for ; Mon, 11 Nov 2019 16:39:20 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 994F7214E0 for ; Mon, 11 Nov 2019 16:39:20 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="M3WZTQbe" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 994F7214E0 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:55056 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iUCil-0000Aj-83 for qemu-devel@archiver.kernel.org; Mon, 11 Nov 2019 11:39:19 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:45113) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iUCgf-0006Xi-1s for qemu-devel@nongnu.org; Mon, 11 Nov 2019 11:37:12 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iUCgb-0004lN-PN for qemu-devel@nongnu.org; Mon, 11 Nov 2019 11:37:08 -0500 Received: from mail-oi1-x22a.google.com ([2607:f8b0:4864:20::22a]:34871) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1iUCgb-0004kz-F4; Mon, 11 Nov 2019 11:37:05 -0500 Received: by mail-oi1-x22a.google.com with SMTP id n16so12043991oig.2; Mon, 11 Nov 2019 08:37:05 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:in-reply-to:references:from:date:message-id:subject:to :cc; bh=JYP7NG+HYTf3HXLqxjKEJMatac/ljNXPWh3jd9LTM+s=; b=M3WZTQberArhSLibbkTNNgKV1JuporTY+QUt37lswJrfwjI7GLilaN9ngG/KG4atf3 NPKNkOy+Jtf96KGZig2awVEkQbrQO/dJYWkiVrB6CCL8TWrr1pLDNWrc55xAy5LwgxUu Lo+9E11MyVWK4YaQqKStQ/V9PMey2O0QG1F3Rx691sBnOClmcNmjOKmDhJiRk5W2GbhA XRLFQVpcjLoRkSutIesDNf1E1i2FF/3Zz8KpTEpDZnAbFt8KZbVX3U/XdHUmscdzAhDp YrqxT1S66Snn08rCnQMU/GfDRLn7gG8HKP2+obZpCU3EfaZT3hdP7x9gEo81O9FMm2kP VI9Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:in-reply-to:references:from:date :message-id:subject:to:cc; bh=JYP7NG+HYTf3HXLqxjKEJMatac/ljNXPWh3jd9LTM+s=; b=rp5UUlmwf8DaJilMi66LhHfT8KCg9tfmvdxvZr9mwmV9nTnwdaYWxqdPQw560xryux bLNDtzzXuKgpkX27KN6luXGdKBYiGjQDV9plXRfjsOHO1VG6ZyTTbBU/lGQKJRptAk6x PfiYfUAD6U2mWHHfcd8PM7xIwosQP0CqOdYlQHiiZlJgvcDRCXVbXJN2CEN1CgeuDIVF m97zwCYNq+mqRcsy7U/eHmFJ0Q+NOg80P3J37De34hX8t514DTMukda5jJRYk2zw4OZ+ xH3q/uNDYuymJMyFzPfcffF9FjbPoKSucz95a9zQrrCSRrvYLwF3d/4+9sIR1Dcljrqt j0+g== X-Gm-Message-State: APjAAAU4FSaAAQIoLkhBpWaRa2VVMhUrI0aLNeVaI33OzT0i1B2nqo0y zu72MHJxiDoMqszBBm1sYyfS+Kdc6Gmf6ZFKnoA= X-Google-Smtp-Source: APXvYqzwWkjo6MpSd5dKItKEywGny0MgHFezLC9HzOf+HCav8E/RoESiXrkyT+AkzIKihgmhqiVLLM3OwTkCjsKR1Vg= X-Received: by 2002:aca:d17:: with SMTP id 23mr1301748oin.136.1573490224084; Mon, 11 Nov 2019 08:37:04 -0800 (PST) MIME-Version: 1.0 Received: by 2002:a05:6830:1391:0:0:0:0 with HTTP; Mon, 11 Nov 2019 08:37:03 -0800 (PST) In-Reply-To: <20191011160552.22907-27-vsementsov@virtuozzo.com> References: <20191011160552.22907-1-vsementsov@virtuozzo.com> <20191011160552.22907-27-vsementsov@virtuozzo.com> From: Aleksandar Markovic Date: Mon, 11 Nov 2019 17:37:03 +0100 Message-ID: Subject: Re: [RFC v5 026/126] python: add commit-per-subsystem.py To: Vladimir Sementsov-Ogievskiy Content-Type: multipart/alternative; boundary="000000000000dd3eff059714bd30" X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::22a X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Ronnie Sahlberg , Jeff Cody , Jan Kiszka , Alberto Garcia , Hailiang Zhang , "qemu-block@nongnu.org" , Aleksandar Rikalo , Halil Pasic , =?UTF-8?Q?Herv=C3=A9_Poussineau?= , Anthony Perard , Samuel Thibault , Laszlo Ersek , Jason Wang , Laurent Vivier , Eduardo Habkost , Xie Changlong , Peter Lieven , "Dr. David Alan Gilbert" , Beniamino Galvani , Eric Auger , Alex Williamson , Stefan Hajnoczi , John Snow , Richard Henderson , Kevin Wolf , Andrew Jeffery , Chris Wulff , Subbaraya Sundeep , Michael Walle , "qemu-ppc@nongnu.org" , Bastian Koppelmann , Igor Mammedov , Fam Zheng , Peter Maydell , "sheepdog@lists.wpkg.org" , Matthew Rosato , David Hildenbrand , Palmer Dabbelt , Eric Farman , Max Filippov , "Denis V. Lunev" , Hannes Reinecke , Stefano Stabellini , "Gonglei \(Arei\)" , Liu Yuan , Artyom Tarasenko , Thomas Huth , Amit Shah , Stefan Weil , Greg Kurz , Yuval Shaia , "qemu-s390x@nongnu.org" , "qemu-arm@nongnu.org" , Peter Chubb , =?UTF-8?Q?C=C3=A9dric_Le_Goater?= , Stafford Horne , "qemu-riscv@nongnu.org" , Cornelia Huck , Aleksandar Markovic , Aurelien Jarno , Paul Burton , Sagar Karandikar , Paul Durrant , Anthony Green , Gerd Hoffmann , "Edgar E. Iglesias" , Guan Xuetao , Ari Sundholm , Juan Quintela , Michael Roth , Christian Borntraeger , Joel Stanley , Jason Dillaman , Antony Pavlov , "xen-devel@lists.xenproject.org" , "integration@gluster.org" , =?UTF-8?Q?Philippe_Mathieu=2DDaud=C3=A9?= , "Richard W.M. Jones" , Andrew Baumann , Max Reitz , "Michael S. Tsirkin" , Mark Cave-Ayland , "qemu-devel@nongnu.org" , Vincenzo Maffione , Marek Vasut , "armbru@redhat.com" , =?UTF-8?B?TWFyYy1BbmRyw6kgTHVyZWF1?= , Alistair Francis , Pavel Dovgalyuk , Giuseppe Lettieri , Luigi Rizzo , David Gibson , Tony Krowiak , =?UTF-8?Q?Daniel_P=2E_Berrang=C3=A9?= , Xiao Guangrong , Pierre Morel , Wen Congyang , Jean-Christophe Dubois , Paolo Bonzini , Stefan Berger Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" --000000000000dd3eff059714bd30 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable On Friday, October 11, 2019, Vladimir Sementsov-Ogievskiy < vsementsov@virtuozzo.com> wrote: > Add script to automatically commit tree-wide changes per-subsystem. > > Signed-off-by: Vladimir Sementsov-Ogievskiy > --- Great idea! Can you just add a comment somewhere close to the top of the file on script usage? Or "--help" option? If you would like to be the script maintainer, please change the MAINTAINERS too. Reviewed-by: Aleksandar Markovic > > CC: Gerd Hoffmann > CC: "Gonglei (Arei)" > CC: Eduardo Habkost > CC: Igor Mammedov > CC: Laurent Vivier > CC: Amit Shah > CC: Kevin Wolf > CC: Max Reitz > CC: John Snow > CC: Ari Sundholm > CC: Pavel Dovgalyuk > CC: Paolo Bonzini > CC: Stefan Hajnoczi > CC: Fam Zheng > CC: Stefan Weil > CC: Ronnie Sahlberg > CC: Peter Lieven > CC: Eric Blake > CC: "Denis V. Lunev" > CC: Markus Armbruster > CC: Alberto Garcia > CC: Jason Dillaman > CC: Wen Congyang > CC: Xie Changlong > CC: Liu Yuan > CC: "Richard W.M. Jones" > CC: Jeff Cody > CC: "Marc-Andr=C3=A9 Lureau" > CC: "Daniel P. Berrang=C3=A9" > CC: Richard Henderson > CC: Greg Kurz > CC: "Michael S. Tsirkin" > CC: Marcel Apfelbaum > CC: Beniamino Galvani > CC: Peter Maydell > CC: "C=C3=A9dric Le Goater" > CC: Andrew Jeffery > CC: Joel Stanley > CC: Andrew Baumann > CC: "Philippe Mathieu-Daud=C3=A9" > CC: Antony Pavlov > CC: Jean-Christophe Dubois > CC: Peter Chubb > CC: Subbaraya Sundeep > CC: Eric Auger > CC: Alistair Francis > CC: "Edgar E. Iglesias" > CC: Stefano Stabellini > CC: Anthony Perard > CC: Paul Durrant > CC: Paul Burton > CC: Aleksandar Rikalo > CC: Chris Wulff > CC: Marek Vasut > CC: David Gibson > CC: Cornelia Huck > CC: Halil Pasic > CC: Christian Borntraeger > CC: "Herv=C3=A9 Poussineau" > CC: Xiao Guangrong > CC: Aurelien Jarno > CC: Aleksandar Markovic > CC: Mark Cave-Ayland > CC: Jason Wang > CC: Laszlo Ersek > CC: Yuval Shaia > CC: Palmer Dabbelt > CC: Sagar Karandikar > CC: Bastian Koppelmann > CC: David Hildenbrand > CC: Thomas Huth > CC: Eric Farman > CC: Matthew Rosato > CC: Hannes Reinecke > CC: Michael Walle > CC: Artyom Tarasenko > CC: Stefan Berger > CC: Samuel Thibault > CC: Alex Williamson > CC: Tony Krowiak > CC: Pierre Morel > CC: Michael Roth > CC: Hailiang Zhang > CC: Juan Quintela > CC: "Dr. David Alan Gilbert" > CC: Luigi Rizzo > CC: Giuseppe Lettieri > CC: Vincenzo Maffione > CC: Jan Kiszka > CC: Anthony Green > CC: Stafford Horne > CC: Guan Xuetao > CC: Max Filippov > CC: qemu-block@nongnu.org > CC: integration@gluster.org > CC: sheepdog@lists.wpkg.org > CC: qemu-arm@nongnu.org > CC: xen-devel@lists.xenproject.org > CC: qemu-ppc@nongnu.org > CC: qemu-s390x@nongnu.org > CC: qemu-riscv@nongnu.org > > python/commit-per-subsystem.py | 204 +++++++++++++++++++++++++++++++++ > 1 file changed, 204 insertions(+) > create mode 100755 python/commit-per-subsystem.py > > diff --git a/python/commit-per-subsystem.py b/python/commit-per-subsystem= . > py > new file mode 100755 > index 0000000000..2ccf84cb15 > --- /dev/null > +++ b/python/commit-per-subsystem.py > @@ -0,0 +1,204 @@ > +#!/usr/bin/env python3 > +# > +# Copyright (c) 2019 Virtuozzo International GmbH > +# > +# This program is free software; you can redistribute it and/or modify > +# it under the terms of the GNU General Public License as published by > +# the Free Software Foundation; either version 2 of the License, or > +# (at your option) any later version. > +# > +# This program is distributed in the hope that it will be useful, > +# but WITHOUT ANY WARRANTY; without even the implied warranty of > +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > +# GNU General Public License for more details. > +# > +# You should have received a copy of the GNU General Public License > +# along with this program. If not, see . > +# > + > +import subprocess > +import sys > +import os > +import glob > + > + > +def git_add(pattern): > + subprocess.run(['git', 'add', pattern]) > + > + > +def git_commit(msg): > + subprocess.run(['git', 'commit', '-m', msg], capture_output=3DTrue) > + > + > +def git_changed_files(): > + ret =3D subprocess.check_output(['git', 'diff', '--name-only'], > encoding=3D'utf-8').split('\n') > + if ret[-1] =3D=3D '': > + del ret[-1] > + return ret > + > + > +maintainers =3D sys.argv[1] > +message =3D sys.argv[2].strip() > + > +subsystem =3D None > + > +remap =3D { > + 'Block layer core': 'block', > + 'Block Jobs': 'block', > + 'Dirty Bitmaps': 'block', > + 'Block QAPI, monitor, command line': 'block', > + 'Block I/O path': 'block', > + 'Throttling infrastructure': 'block', > + 'Architecture support': 's390x', > + 'Guest CPU Cores (KVM)': 'kvm', > + 'Guest CPU Cores (Xen)': 'xen', > + 'Guest CPU cores (TCG)': 'tcg', > + 'Network Block Device (NBD)': 'nbd', > + 'Parallel NOR Flash devices': 'pflash', > + 'Firmware configuration (fw_cfg)': 'fw_cfg', > + 'Block SCSI subsystem': 'scsi', > + 'Network device backends': 'net', > + 'Netmap network backend': 'net', > + 'Host Memory Backends': 'hostmem', > + 'Cryptodev Backends': 'cryptodev', > + 'QEMU Guest Agent': 'qga', > + 'COLO Framework': 'colo', > + 'Command line option argument parsing': 'cmdline', > + 'Character device backends': 'chardev' > +} > + > + > +class Maintainers: > + def add(self, subsystem, path, mapper, mapper_name, glob_count=3D1): > + if subsystem in remap: > + subsystem =3D remap[subsystem] > + if subsystem not in self.subsystems: > + self.subsystems.append(subsystem) > + > + if path[-1] =3D=3D '/': > + path =3D path[:-1] > + > + if path in mapper: > + if mapper[path][1] =3D=3D glob_count: > + print('Warning: "{}" both in "{}" and "{}" in {} mapper > with ' > + 'same glob-count=3D{}. {} ignored for this > path.'.format( > + path, mapper[path][0], subsystem, mapper_name, > glob_count, > + subsystem)) > + return > + if mapper[path][1] < glob_count: > + # silently ignore worse match > + return > + > + mapper[path] =3D (subsystem, glob_count) > + > + def __init__(self, file_name): > + self.map_file =3D {} > + self.map_glob_file =3D {} > + self.map_dir =3D {} > + self.map_glob_dir =3D {} > + self.map_unmaintained_dir =3D { > + 'python': ('python', 1), > + 'hw/misc': ('misc', 1) > + } > + self.subsystems =3D ['python', 'misc'] > + subsystem =3D None > + > + with open(file_name) as f: > + mode2 =3D False > + prevline =3D '' > + for line in f: > + line =3D line.rstrip() > + if not line: > + continue > + if len(line) >=3D 2 and line[1] =3D=3D ':': > + if line[0] =3D=3D 'F': > + fname =3D line[3:] > + if fname in ['*', '*/']: > + continue > + if os.path.isfile(fname): > + self.add(subsystem, fname, self.map_file, > 'file') > + elif os.path.isdir(fname): > + self.add(subsystem, fname, self.map_dir, > 'dir') > + else: > + paths =3D glob.glob(fname) > + if not paths: > + print('Warning: nothing corresponds to > "{}"'.format(fname)) > + continue > + > + n =3D len(paths) > + for f in paths: > + if os.path.isfile(f): > + self.add(subsystem, f, > self.map_glob_file, 'glob-file', n) > + else: > + assert os.path.isdir(f) > + self.add(subsystem, f, > self.map_glob_dir, 'glob-dir', n) > + elif line[:3] =3D=3D '---': > + subsystem =3D prevline > + if subsystem =3D=3D 'Devices': > + mode2 =3D True > + elif mode2: > + subsystem =3D line > + prevline =3D line > + > + def find_in_map_dir(self, file_name, mapper): > + while file_name !=3D '' and file_name not in mapper: > + file_name =3D os.path.dirname(file_name) > + > + return None if file_name =3D=3D '' else mapper[file_name][0] > + > + def find_in_map_file(self, file_name, mapper): > + if file_name in mapper: > + return mapper[file_name][0] > + > + def find_subsystem(self, file_name): > + s =3D self.find_in_map_file(file_name, self.map_file) > + if s is not None: > + return s > + > + s =3D self.find_in_map_file(file_name, self.map_glob_file) > + if s is not None: > + return s > + > + s =3D self.find_in_map_dir(file_name, self.map_dir) > + if s is not None: > + return s > + > + s =3D self.find_in_map_dir(file_name, self.map_glob_dir) > + if s is not None: > + return s > + > + s =3D self.find_in_map_dir(file_name, self.map_unmaintained_dir) > + if s is not None: > + return s > + > + self.subsystems.append(file_name) > + return file_name > + > + > +def commit(subsystem): > + msg =3D subsystem > + if msg in remap: > + msg =3D remap[msg] > + msg +=3D ': ' + message > + git_commit(msg) > + > +mnt =3D Maintainers(maintainers) > +res =3D {} > +for f in git_changed_files(): > + s =3D mnt.find_subsystem(f) > + if s in res: > + res[s].append(f) > + else: > + res[s] =3D [f] > + > +for s in mnt.subsystems: > + if s in res: > + print(s) > + for f in res[s]: > + print(' ', f) > + > +for s in mnt.subsystems: > + if s in res: > + for f in res[s]: > + git_add(f) > + commit(s) > -- > 2.21.0 > > > --000000000000dd3eff059714bd30 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable

On Friday, October 11, 2019, Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> wro= te:
Add script to automatically commit tr= ee-wide changes per-subsystem.

Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
---

Great idea!

Ca= n you just add a comment somewhere close to the top of the file on script u= sage? Or "--help" option? If you would like to be the script main= tainer, please change the MAINTAINERS too.

Reviewe= d-by: Aleksandar Markovic <ama= rkovic@wavecomp.com>
=C2=A0

CC: Gerd Hoffmann <kraxel@redhat.co= m>
CC: "Gonglei (Arei)" <arei.gonglei@huawei.com>
CC: Eduardo Habkost <ehabkost@red= hat.com>
CC: Igor Mammedov <imammedo@redha= t.com>
CC: Laurent Vivier <lvivier@redhat= .com>
CC: Amit Shah <amit@kernel.org>= ;
CC: Kevin Wolf <kwolf@redhat.com= >
CC: Max Reitz <mreitz@redhat.com>
CC: John Snow <
jsnow@redhat.com&= gt;
CC: Ari Sundholm <ari@tuxera.com&g= t;
CC: Pavel Dovgalyuk <pavel.d= ovgaluk@ispras.ru>
CC: Paolo Bonzini <pbonzini@redha= t.com>
CC: Stefan Hajnoczi <stefanha@red= hat.com>
CC: Fam Zheng <fam@euphon.net><= br> CC: Stefan Weil <sw@weilnetz.de>= ;
CC: Ronnie Sahlberg <ronnies= ahlberg@gmail.com>
CC: Peter Lieven <pl@kamp.de>
CC: Eric Blake <eblake@redhat.com>
CC: "Denis V. Lunev" <
den@op= envz.org>
CC: Markus Armbruster <armbru@redha= t.com>
CC: Alberto Garcia <berto@igalia.com= >
CC: Jason Dillaman <dillaman@redh= at.com>
CC: Wen Congyang <wencongyang= 2@huawei.com>
CC: Xie Changlong <xiechangl= ong.d@gmail.com>
CC: Liu Yuan <namei.unix@gmail.c= om>
CC: "Richard W.M. Jones" <rjones@redhat.com>
CC: Jeff Cody <codyprime@gmail.co= m>
CC: "Marc-Andr=C3=A9 Lureau" <marcandre.lureau@redhat.com>
CC: "Daniel P. Berrang=C3=A9" <berrange@redhat.com>
CC: Richard Henderson <rth@twiddle.ne= t>
CC: Greg Kurz <groug@kaod.org><= br> CC: "Michael S. Tsirkin" <ms= t@redhat.com>
CC: Marcel Apfelbaum <marc= el.apfelbaum@gmail.com>
CC: Beniamino Galvani <b.galvani@= gmail.com>
CC: Peter Maydell <peter.may= dell@linaro.org>
CC: "C=C3=A9dric Le Goater" <c= lg@kaod.org>
CC: Andrew Jeffery <andrew@aj.id.au>
CC: Joel Stanley <
joel@jms.id.au&g= t;
CC: Andrew Baumann <Andr= ew.Baumann@microsoft.com>
CC: "Philippe Mathieu-Daud=C3=A9" <philmd@redhat.com>
CC: Antony Pavlov <antonynpav= lov@gmail.com>
CC: Jean-Christophe Dubois <jcd@t= ribudubois.net>
CC: Peter Chubb <peter.chubb= @nicta.com.au>
CC: Subbaraya Sundeep <sundeep= .lkml@gmail.com>
CC: Eric Auger <eric.auger@redh= at.com>
CC: Alistair Francis <alistair= @alistair23.me>
CC: "Edgar E. Iglesias" <edgar.iglesias@gmail.com>
CC: Stefano Stabellini <sstabe= llini@kernel.org>
CC: Anthony Perard <anthony= .perard@citrix.com>
CC: Paul Durrant <paul@xen.org> CC: Paul Burton <pburton@wavecom= p.com>
CC: Aleksandar Rikalo <arikalo@w= avecomp.com>
CC: Chris Wulff <crwulff@gmail.com<= /a>>
CC: Marek Vasut <
marex@denx.de><= br> CC: David Gibson <david@g= ibson.dropbear.id.au>
CC: Cornelia Huck <cohuck@redhat.co= m>
CC: Halil Pasic <pasic@linux.ibm.= com>
CC: Christian Borntraeger <bor= ntraeger@de.ibm.com>
CC: "Herv=C3=A9 Poussineau" <hpoussin@reactos.org>
CC: Xiao Guangrong <xiao= guangrong.eric@gmail.com>
CC: Aurelien Jarno <aurelien@aur= el32.net>
CC: Aleksandar Markovic <amark= ovic@wavecomp.com>
CC: Mark Cave-Ayland <m= ark.cave-ayland@ilande.co.uk>
CC: Jason Wang <jasowang@redhat.c= om>
CC: Laszlo Ersek <lersek@redhat.com= >
CC: Yuval Shaia <yuval.shaia@o= racle.com>
CC: Palmer Dabbelt <palmer@sifive.c= om>
CC: Sagar Karandikar <sagark= @eecs.berkeley.edu>
CC: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
CC: David Hildenbrand <david@redhat.= com>
CC: Thomas Huth <thuth@redhat.com>
CC: Eric Farman <
farman@linux.ib= m.com>
CC: Matthew Rosato <mjrosato@l= inux.ibm.com>
CC: Hannes Reinecke <hare@suse.com&= gt;
CC: Michael Walle <michael@walle.cc>
CC: Artyom Tarasenko <atar4qemu@g= mail.com>
CC: Stefan Berger <stefanb@linu= x.ibm.com>
CC: Samuel Thibault <sam= uel.thibault@ens-lyon.org>
CC: Alex Williamson <alex.= williamson@redhat.com>
CC: Tony Krowiak <akrowiak@lin= ux.ibm.com>
CC: Pierre Morel <pmorel@linux.i= bm.com>
CC: Michael Roth <mdroth@li= nux.vnet.ibm.com>
CC: Hailiang Zhang <zh= ang.zhanghailiang@huawei.com>
CC: Juan Quintela <quintela@redha= t.com>
CC: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
CC: Luigi Rizzo <rizzo@iet.unipi.i= t>
CC: Giuseppe Lettieri <g.lett= ieri@iet.unipi.it>
CC: Vincenzo Maffione <v.maffion= e@gmail.com>
CC: Jan Kiszka <jan.kiszka@sie= mens.com>
CC: Anthony Green <green@moxielo= gic.com>
CC: Stafford Horne <shorne@gmail.com= >
CC: Guan Xuetao <gxt@mprc.pku.edu= .cn>
CC: Max Filippov <jcmvbkbc@gmail.c= om>
CC: qemu-block@nongnu.org
CC: integration@gluster.org<= br> CC: sheepdog@lists.wpkg.org<= br> CC: qemu-arm@nongnu.org
CC: xen-devel@lists.xenpr= oject.org
CC: qemu-ppc@nongnu.org
CC: qemu-s390x@nongnu.org
CC: qemu-riscv@nongnu.org

=C2=A0python/commit-per-subsystem.py | 204 +++++++++++++++++++++++++++++++++
=C2=A01 file changed, 204 insertions(+)
=C2=A0create mode 100755 python/commit-per-subsystem.py

diff --git a/python/commit-per-subsystem.py b/python/commit-per-subsys= tem.py
new file mode 100755
index 0000000000..2ccf84cb15
--- /dev/null
+++ b/python/commit-per-subsystem.py
@@ -0,0 +1,204 @@
+#!/usr/bin/env python3
+#
+# Copyright (c) 2019 Virtuozzo International GmbH
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.=C2=A0 See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.=C2=A0 If not, see <http://www.gnu.org/licenses/>= .
+#
+
+import subprocess
+import sys
+import os
+import glob
+
+
+def git_add(pattern):
+=C2=A0 =C2=A0 subprocess.run(['git', 'add', pattern])
+
+
+def git_commit(msg):
+=C2=A0 =C2=A0 subprocess.run(['git', 'commit', '-m'= ;, msg], capture_output=3DTrue)
+
+
+def git_changed_files():
+=C2=A0 =C2=A0 ret =3D subprocess.check_output(['git', 'di= ff', '--name-only'], encoding=3D'utf-8').split('\n&= #39;)
+=C2=A0 =C2=A0 if ret[-1] =3D=3D '':
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 del ret[-1]
+=C2=A0 =C2=A0 return ret
+
+
+maintainers =3D sys.argv[1]
+message =3D sys.argv[2].strip()
+
+subsystem =3D None
+
+remap =3D {
+=C2=A0 =C2=A0 'Block layer core': 'block',
+=C2=A0 =C2=A0 'Block Jobs': 'block',
+=C2=A0 =C2=A0 'Dirty Bitmaps': 'block',
+=C2=A0 =C2=A0 'Block QAPI, monitor, command line': 'block'= ,
+=C2=A0 =C2=A0 'Block I/O path': 'block',
+=C2=A0 =C2=A0 'Throttling infrastructure': 'block',
+=C2=A0 =C2=A0 'Architecture support': 's390x',
+=C2=A0 =C2=A0 'Guest CPU Cores (KVM)': 'kvm',
+=C2=A0 =C2=A0 'Guest CPU Cores (Xen)': 'xen',
+=C2=A0 =C2=A0 'Guest CPU cores (TCG)': 'tcg',
+=C2=A0 =C2=A0 'Network Block Device (NBD)': 'nbd',
+=C2=A0 =C2=A0 'Parallel NOR Flash devices': 'pflash',
+=C2=A0 =C2=A0 'Firmware configuration (fw_cfg)': 'fw_cfg',=
+=C2=A0 =C2=A0 'Block SCSI subsystem': 'scsi',
+=C2=A0 =C2=A0 'Network device backends': 'net',
+=C2=A0 =C2=A0 'Netmap network backend': 'net',
+=C2=A0 =C2=A0 'Host Memory Backends': 'hostmem',
+=C2=A0 =C2=A0 'Cryptodev Backends': 'cryptodev',
+=C2=A0 =C2=A0 'QEMU Guest Agent': 'qga',
+=C2=A0 =C2=A0 'COLO Framework': 'colo',
+=C2=A0 =C2=A0 'Command line option argument parsing': 'cmdline= ',
+=C2=A0 =C2=A0 'Character device backends': 'chardev'
+}
+
+
+class Maintainers:
+=C2=A0 =C2=A0 def add(self, subsystem, path, mapper, mapper_name, glob_cou= nt=3D1):
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 if subsystem in remap:
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 subsystem =3D remap[subsystem] +=C2=A0 =C2=A0 =C2=A0 =C2=A0 if subsystem not in self.subsystems:
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 self.subsystems.append(subs= ystem)
+
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 if path[-1] =3D=3D '/':
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 path =3D path[:-1]
+
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 if path in mapper:
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if mapper[path][1] =3D=3D glob_c= ount:
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 print('Warning= : "{}" both in "{}" and "{}" in {} mapper wit= h '
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 'same glob-count=3D{}. {} ignored for this path.'.format(
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 path, mapper[path][0], subsystem, mapper_name, glob_count,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 subsystem))
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if mapper[path][1] < glob_cou= nt:
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 # silently ignore = worse match
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return
+
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 mapper[path] =3D (subsystem, glob_count)
+
+=C2=A0 =C2=A0 def __init__(self, file_name):
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 self.map_file =3D {}
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 self.map_glob_file =3D {}
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 self.map_dir =3D {}
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 self.map_glob_dir =3D {}
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 self.map_unmaintained_dir =3D {
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 'python': ('python&#= 39;, 1),
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 'hw/misc': ('misc= 9;, 1)
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 }
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 self.subsystems =3D ['python', 'mi= sc']
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 subsystem =3D None
+
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 with open(file_name) as f:
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 mode2 =3D False
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 prevline =3D ''
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 for line in f:
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 line =3D line.rstr= ip()
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if not line:
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 cont= inue
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if len(line) >= =3D 2 and line[1] =3D=3D ':':
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if l= ine[0] =3D=3D 'F':
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 fname =3D line[3:]
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 if fname in ['*', '*/']:
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 continue
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 if os.path.isfile(fname):
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 self.add(subsystem, fname, self.map_file, 'fil= e')
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 elif os.path.isdir(fname):
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 self.add(subsystem, fname, self.map_dir, 'dir&= #39;)
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 else:
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 paths =3D glob.glob(fname)
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 if not paths:
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 print('Warning: nothing correspo= nds to "{}"'.format(fname))
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 continue
+
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 n =3D len(paths)
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 for f in paths:
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if os.path.isfile(f):
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 self.add(subsystem, f,= self.map_glob_file, 'glob-file', n)
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 else:
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 assert os.path.isdir(f= )
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 self.add(subsystem, f,= self.map_glob_dir, 'glob-dir', n)
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 elif line[:3] =3D= =3D '---':
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 subs= ystem =3D prevline
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if s= ubsystem =3D=3D 'Devices':
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 mode2 =3D True
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 elif mode2:
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 subs= ystem =3D line
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 prevline =3D line<= br> +
+=C2=A0 =C2=A0 def find_in_map_dir(self, file_name, mapper):
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 while file_name !=3D '' and file_name = not in mapper:
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 file_name =3D os.path.dirname(fi= le_name)
+
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 return None if file_name =3D=3D '' els= e mapper[file_name][0]
+
+=C2=A0 =C2=A0 def find_in_map_file(self, file_name, mapper):
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 if file_name in mapper:
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return mapper[file_name][0]
+
+=C2=A0 =C2=A0 def find_subsystem(self, file_name):
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 s =3D self.find_in_map_file(file_name, se= lf.map_file)
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 if s is not None:
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return s
+
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 s =3D self.find_in_map_file(file_name, se= lf.map_glob_file)
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 if s is not None:
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return s
+
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 s =3D self.find_in_map_dir(file_name, sel= f.map_dir)
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 if s is not None:
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return s
+
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 s =3D self.find_in_map_dir(file_name, sel= f.map_glob_dir)
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 if s is not None:
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return s
+
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 s =3D self.find_in_map_dir(file_name, sel= f.map_unmaintained_dir)
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 if s is not None:
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return s
+
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 self.subsystems.append(file_name)
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 return file_name
+
+
+def commit(subsystem):
+=C2=A0 =C2=A0 msg =3D subsystem
+=C2=A0 =C2=A0 if msg in remap:
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 msg =3D remap[msg]
+=C2=A0 =C2=A0 msg +=3D ': ' + message
+=C2=A0 =C2=A0 git_commit(msg)
+
+mnt =3D Maintainers(maintainers)
+res =3D {}
+for f in git_changed_files():
+=C2=A0 =C2=A0 s =3D mnt.find_subsystem(f)
+=C2=A0 =C2=A0 if s in res:
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 res[s].append(f)
+=C2=A0 =C2=A0 else:
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 res[s] =3D [f]
+
+for s in mnt.subsystems:
+=C2=A0 =C2=A0 if s in res:
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 print(s)
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 for f in res[s]:
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 print('=C2=A0 ', f)
+
+for s in mnt.subsystems:
+=C2=A0 =C2=A0 if s in res:
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 for f in res[s]:
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 git_add(f)
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 commit(s)
--
2.21.0


--000000000000dd3eff059714bd30--