patch-manager 0.0.7__tar.gz → 0.0.8__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. patch_manager-0.0.8/PKG-INFO +117 -0
  2. patch_manager-0.0.8/README.rst +80 -0
  3. patch_manager-0.0.8/patch_manager.egg-info/PKG-INFO +117 -0
  4. patch_manager-0.0.8/patch_manager.egg-info/SOURCES.txt +54 -0
  5. patch_manager-0.0.8/patch_manager.egg-info/requires.txt +20 -0
  6. patch_manager-0.0.8/patch_manager.egg-info/top_level.txt +2 -0
  7. {patch_manager-0.0.7/src → patch_manager-0.0.8}/patman/__init__.py +1 -1
  8. {patch_manager-0.0.7/src → patch_manager-0.0.8}/patman/__main__.py +5 -3
  9. {patch_manager-0.0.7/src → patch_manager-0.0.8}/patman/checkpatch.py +22 -5
  10. {patch_manager-0.0.7/src → patch_manager-0.0.8}/patman/cmdline.py +242 -9
  11. {patch_manager-0.0.7/src → patch_manager-0.0.8}/patman/commit.py +2 -0
  12. {patch_manager-0.0.7/src → patch_manager-0.0.8}/patman/control.py +220 -45
  13. {patch_manager-0.0.7/src → patch_manager-0.0.8}/patman/cser_helper.py +167 -47
  14. {patch_manager-0.0.7/src → patch_manager-0.0.8}/patman/cseries.py +652 -78
  15. patch_manager-0.0.8/patman/database.py +1533 -0
  16. {patch_manager-0.0.7/src → patch_manager-0.0.8}/patman/func_test.py +28 -20
  17. patch_manager-0.0.8/patman/gmail.py +591 -0
  18. {patch_manager-0.0.7/src → patch_manager-0.0.8}/patman/patchstream.py +77 -13
  19. {patch_manager-0.0.7/src → patch_manager-0.0.8}/patman/patchwork.py +109 -9
  20. patch_manager-0.0.7/src/patch_manager.egg-info/PKG-INFO → patch_manager-0.0.8/patman/patman.rst +669 -18
  21. patch_manager-0.0.8/patman/review.py +2423 -0
  22. {patch_manager-0.0.7/src → patch_manager-0.0.8}/patman/send.py +27 -7
  23. {patch_manager-0.0.7/src → patch_manager-0.0.8}/patman/series.py +3 -1
  24. {patch_manager-0.0.7/src → patch_manager-0.0.8}/patman/settings.py +1 -1
  25. {patch_manager-0.0.7/src → patch_manager-0.0.8}/patman/status.py +58 -1
  26. patch_manager-0.0.8/patman/test/0000-cover-letter.patch +23 -0
  27. patch_manager-0.0.8/patman/test/0001-pci-Correct-cast-for-sandbox.patch +51 -0
  28. patch_manager-0.0.8/patman/test/0002-fdt-Correct-cast-for-sandbox-in-fdtdec_setup_mem_siz.patch +85 -0
  29. patch_manager-0.0.8/patman/test/get_maintainer +66 -0
  30. patch_manager-0.0.8/patman/test/maintainers +11 -0
  31. patch_manager-0.0.8/patman/test/test01.txt +72 -0
  32. {patch_manager-0.0.7/src → patch_manager-0.0.8}/patman/test_checkpatch.py +69 -12
  33. {patch_manager-0.0.7/src → patch_manager-0.0.8}/patman/test_common.py +1 -0
  34. {patch_manager-0.0.7/src → patch_manager-0.0.8}/patman/test_cseries.py +1805 -99
  35. patch_manager-0.0.8/patman/workflow.py +174 -0
  36. patch_manager-0.0.8/pyproject.toml +62 -0
  37. patch_manager-0.0.8/u_boot_pylib/__init__.py +4 -0
  38. patch_manager-0.0.8/u_boot_pylib/__main__.py +46 -0
  39. patch_manager-0.0.8/u_boot_pylib/claude.py +77 -0
  40. patch_manager-0.0.8/u_boot_pylib/command.py +291 -0
  41. patch_manager-0.0.8/u_boot_pylib/cros_subprocess.py +402 -0
  42. patch_manager-0.0.8/u_boot_pylib/gitutil.py +1062 -0
  43. patch_manager-0.0.8/u_boot_pylib/terminal.py +350 -0
  44. patch_manager-0.0.8/u_boot_pylib/test_claude.py +142 -0
  45. patch_manager-0.0.8/u_boot_pylib/test_command.py +58 -0
  46. patch_manager-0.0.8/u_boot_pylib/test_gitutil.py +122 -0
  47. patch_manager-0.0.8/u_boot_pylib/test_util.py +235 -0
  48. patch_manager-0.0.8/u_boot_pylib/tools.py +612 -0
  49. patch_manager-0.0.8/u_boot_pylib/tout.py +190 -0
  50. patch_manager-0.0.7/PKG-INFO +0 -1040
  51. patch_manager-0.0.7/README.rst +0 -1023
  52. patch_manager-0.0.7/pyproject.toml +0 -29
  53. patch_manager-0.0.7/src/patch_manager.egg-info/SOURCES.txt +0 -34
  54. patch_manager-0.0.7/src/patch_manager.egg-info/requires.txt +0 -2
  55. patch_manager-0.0.7/src/patch_manager.egg-info/top_level.txt +0 -1
  56. patch_manager-0.0.7/src/patman/README.rst +0 -1023
  57. patch_manager-0.0.7/src/patman/database.py +0 -823
  58. patch_manager-0.0.7/src/patman/patman.rst +0 -1023
  59. patch_manager-0.0.7/src/patman/setup.py +0 -11
  60. {patch_manager-0.0.7 → patch_manager-0.0.8}/LICENSE +0 -0
  61. {patch_manager-0.0.7/src → patch_manager-0.0.8}/patch_manager.egg-info/dependency_links.txt +0 -0
  62. {patch_manager-0.0.7/src → patch_manager-0.0.8}/patch_manager.egg-info/entry_points.txt +0 -0
  63. {patch_manager-0.0.7/src → patch_manager-0.0.8}/patman/get_maintainer.py +0 -0
  64. {patch_manager-0.0.7/src → patch_manager-0.0.8}/patman/project.py +0 -0
  65. {patch_manager-0.0.7/src → patch_manager-0.0.8}/patman/test_settings.py +0 -0
  66. {patch_manager-0.0.7 → patch_manager-0.0.8}/setup.cfg +0 -0
@@ -0,0 +1,117 @@
1
+ Metadata-Version: 2.4
2
+ Name: patch-manager
3
+ Version: 0.0.8
4
+ Summary: Create, check and email patch series, with Patchwork integration
5
+ Author-email: Simon Glass <sjg@chromium.org>
6
+ License-Expression: GPL-2.0-or-later
7
+ Project-URL: Homepage, https://github.com/nxtboot/patman
8
+ Project-URL: Documentation, https://patman.readthedocs.io/
9
+ Project-URL: Repository, https://github.com/nxtboot/patman
10
+ Project-URL: Bug Tracker, https://github.com/nxtboot/patman/issues
11
+ Keywords: patch,email,git,patchwork,u-boot,review
12
+ Classifier: Programming Language :: Python :: 3
13
+ Classifier: Operating System :: OS Independent
14
+ Classifier: Environment :: Console
15
+ Classifier: Topic :: Software Development :: Version Control :: Git
16
+ Classifier: Intended Audience :: Developers
17
+ Requires-Python: >=3.9
18
+ Description-Content-Type: text/x-rst
19
+ License-File: LICENSE
20
+ Requires-Dist: pygit2>=1.14
21
+ Requires-Dist: aiohttp>=3.9
22
+ Provides-Extra: gmail
23
+ Requires-Dist: google-api-python-client; extra == "gmail"
24
+ Requires-Dist: google-auth-httplib2; extra == "gmail"
25
+ Requires-Dist: google-auth-oauthlib; extra == "gmail"
26
+ Provides-Extra: review
27
+ Requires-Dist: claude-agent-sdk; extra == "review"
28
+ Provides-Extra: test
29
+ Requires-Dist: concurrencytest; extra == "test"
30
+ Provides-Extra: all
31
+ Requires-Dist: google-api-python-client; extra == "all"
32
+ Requires-Dist: google-auth-httplib2; extra == "all"
33
+ Requires-Dist: google-auth-oauthlib; extra == "all"
34
+ Requires-Dist: claude-agent-sdk; extra == "all"
35
+ Requires-Dist: concurrencytest; extra == "all"
36
+ Dynamic: license-file
37
+
38
+ Patman patch manager
39
+ ====================
40
+
41
+ .. image:: https://github.com/nxtboot/patman/actions/workflows/test.yml/badge.svg
42
+ :target: https://github.com/nxtboot/patman/actions/workflows/test.yml
43
+ :alt: Test status
44
+
45
+ .. image:: https://img.shields.io/pypi/v/patch-manager.svg
46
+ :target: https://pypi.org/project/patch-manager/
47
+ :alt: PyPI version
48
+
49
+ .. image:: https://readthedocs.org/projects/patman/badge/?version=latest
50
+ :target: https://patman.readthedocs.io/en/latest/
51
+ :alt: Documentation status
52
+
53
+ .. image:: https://img.shields.io/pypi/pyversions/patch-manager.svg
54
+ :target: https://pypi.org/project/patch-manager/
55
+ :alt: Supported Python versions
56
+
57
+ Patman is a command-line tool that automates the boring parts of preparing
58
+ and sending patches by email, in the style used by the U-Boot and Linux
59
+ kernel projects. It:
60
+
61
+ - creates patches directly from a git branch;
62
+ - cleans them up by removing unwanted tags and inserting a cover letter;
63
+ - runs checkpatch.pl and the project's checks before anything is sent;
64
+ - looks up the maintainers to Cc, and emails the series out;
65
+ - tracks series in a local database and integrates with Patchwork to gather
66
+ review tags and follow up on comments.
67
+
68
+ Installation
69
+ ------------
70
+
71
+ Install the latest release from PyPI::
72
+
73
+ pip install patch-manager
74
+
75
+ Optional features are available as extras::
76
+
77
+ pip install patch-manager[gmail] # send/fetch review mail via Gmail
78
+ pip install patch-manager[review] # AI-assisted patch review
79
+ pip install patch-manager[all] # everything
80
+
81
+ The ``patman`` command is then on your path.
82
+
83
+ Quick start
84
+ -----------
85
+
86
+ From a git branch containing the commits you want to send::
87
+
88
+ patman # create, check and email the series
89
+ patman -n # dry run: create and check, but do not send
90
+
91
+ See ``patman --full-help`` for the complete manual, or the documentation
92
+ linked below.
93
+
94
+ Documentation
95
+ -------------
96
+
97
+ Full documentation is hosted on Read the Docs:
98
+
99
+ https://patman.readthedocs.io/
100
+
101
+ Development
102
+ -----------
103
+
104
+ Run the test suite from a checkout::
105
+
106
+ pip install -r requirements.txt
107
+ pip install -e .
108
+ patman test
109
+
110
+ The suite is self-contained: a pinned ``checkpatch.pl`` and its helper files
111
+ live in ``scripts/``, and the bundled ``u_boot_pylib`` package is vendored in
112
+ the tree, so no surrounding U-Boot source is required.
113
+
114
+ License
115
+ -------
116
+
117
+ GPL-2.0-or-later. See the ``LICENSE`` file for the full text.
@@ -0,0 +1,80 @@
1
+ Patman patch manager
2
+ ====================
3
+
4
+ .. image:: https://github.com/nxtboot/patman/actions/workflows/test.yml/badge.svg
5
+ :target: https://github.com/nxtboot/patman/actions/workflows/test.yml
6
+ :alt: Test status
7
+
8
+ .. image:: https://img.shields.io/pypi/v/patch-manager.svg
9
+ :target: https://pypi.org/project/patch-manager/
10
+ :alt: PyPI version
11
+
12
+ .. image:: https://readthedocs.org/projects/patman/badge/?version=latest
13
+ :target: https://patman.readthedocs.io/en/latest/
14
+ :alt: Documentation status
15
+
16
+ .. image:: https://img.shields.io/pypi/pyversions/patch-manager.svg
17
+ :target: https://pypi.org/project/patch-manager/
18
+ :alt: Supported Python versions
19
+
20
+ Patman is a command-line tool that automates the boring parts of preparing
21
+ and sending patches by email, in the style used by the U-Boot and Linux
22
+ kernel projects. It:
23
+
24
+ - creates patches directly from a git branch;
25
+ - cleans them up by removing unwanted tags and inserting a cover letter;
26
+ - runs checkpatch.pl and the project's checks before anything is sent;
27
+ - looks up the maintainers to Cc, and emails the series out;
28
+ - tracks series in a local database and integrates with Patchwork to gather
29
+ review tags and follow up on comments.
30
+
31
+ Installation
32
+ ------------
33
+
34
+ Install the latest release from PyPI::
35
+
36
+ pip install patch-manager
37
+
38
+ Optional features are available as extras::
39
+
40
+ pip install patch-manager[gmail] # send/fetch review mail via Gmail
41
+ pip install patch-manager[review] # AI-assisted patch review
42
+ pip install patch-manager[all] # everything
43
+
44
+ The ``patman`` command is then on your path.
45
+
46
+ Quick start
47
+ -----------
48
+
49
+ From a git branch containing the commits you want to send::
50
+
51
+ patman # create, check and email the series
52
+ patman -n # dry run: create and check, but do not send
53
+
54
+ See ``patman --full-help`` for the complete manual, or the documentation
55
+ linked below.
56
+
57
+ Documentation
58
+ -------------
59
+
60
+ Full documentation is hosted on Read the Docs:
61
+
62
+ https://patman.readthedocs.io/
63
+
64
+ Development
65
+ -----------
66
+
67
+ Run the test suite from a checkout::
68
+
69
+ pip install -r requirements.txt
70
+ pip install -e .
71
+ patman test
72
+
73
+ The suite is self-contained: a pinned ``checkpatch.pl`` and its helper files
74
+ live in ``scripts/``, and the bundled ``u_boot_pylib`` package is vendored in
75
+ the tree, so no surrounding U-Boot source is required.
76
+
77
+ License
78
+ -------
79
+
80
+ GPL-2.0-or-later. See the ``LICENSE`` file for the full text.
@@ -0,0 +1,117 @@
1
+ Metadata-Version: 2.4
2
+ Name: patch-manager
3
+ Version: 0.0.8
4
+ Summary: Create, check and email patch series, with Patchwork integration
5
+ Author-email: Simon Glass <sjg@chromium.org>
6
+ License-Expression: GPL-2.0-or-later
7
+ Project-URL: Homepage, https://github.com/nxtboot/patman
8
+ Project-URL: Documentation, https://patman.readthedocs.io/
9
+ Project-URL: Repository, https://github.com/nxtboot/patman
10
+ Project-URL: Bug Tracker, https://github.com/nxtboot/patman/issues
11
+ Keywords: patch,email,git,patchwork,u-boot,review
12
+ Classifier: Programming Language :: Python :: 3
13
+ Classifier: Operating System :: OS Independent
14
+ Classifier: Environment :: Console
15
+ Classifier: Topic :: Software Development :: Version Control :: Git
16
+ Classifier: Intended Audience :: Developers
17
+ Requires-Python: >=3.9
18
+ Description-Content-Type: text/x-rst
19
+ License-File: LICENSE
20
+ Requires-Dist: pygit2>=1.14
21
+ Requires-Dist: aiohttp>=3.9
22
+ Provides-Extra: gmail
23
+ Requires-Dist: google-api-python-client; extra == "gmail"
24
+ Requires-Dist: google-auth-httplib2; extra == "gmail"
25
+ Requires-Dist: google-auth-oauthlib; extra == "gmail"
26
+ Provides-Extra: review
27
+ Requires-Dist: claude-agent-sdk; extra == "review"
28
+ Provides-Extra: test
29
+ Requires-Dist: concurrencytest; extra == "test"
30
+ Provides-Extra: all
31
+ Requires-Dist: google-api-python-client; extra == "all"
32
+ Requires-Dist: google-auth-httplib2; extra == "all"
33
+ Requires-Dist: google-auth-oauthlib; extra == "all"
34
+ Requires-Dist: claude-agent-sdk; extra == "all"
35
+ Requires-Dist: concurrencytest; extra == "all"
36
+ Dynamic: license-file
37
+
38
+ Patman patch manager
39
+ ====================
40
+
41
+ .. image:: https://github.com/nxtboot/patman/actions/workflows/test.yml/badge.svg
42
+ :target: https://github.com/nxtboot/patman/actions/workflows/test.yml
43
+ :alt: Test status
44
+
45
+ .. image:: https://img.shields.io/pypi/v/patch-manager.svg
46
+ :target: https://pypi.org/project/patch-manager/
47
+ :alt: PyPI version
48
+
49
+ .. image:: https://readthedocs.org/projects/patman/badge/?version=latest
50
+ :target: https://patman.readthedocs.io/en/latest/
51
+ :alt: Documentation status
52
+
53
+ .. image:: https://img.shields.io/pypi/pyversions/patch-manager.svg
54
+ :target: https://pypi.org/project/patch-manager/
55
+ :alt: Supported Python versions
56
+
57
+ Patman is a command-line tool that automates the boring parts of preparing
58
+ and sending patches by email, in the style used by the U-Boot and Linux
59
+ kernel projects. It:
60
+
61
+ - creates patches directly from a git branch;
62
+ - cleans them up by removing unwanted tags and inserting a cover letter;
63
+ - runs checkpatch.pl and the project's checks before anything is sent;
64
+ - looks up the maintainers to Cc, and emails the series out;
65
+ - tracks series in a local database and integrates with Patchwork to gather
66
+ review tags and follow up on comments.
67
+
68
+ Installation
69
+ ------------
70
+
71
+ Install the latest release from PyPI::
72
+
73
+ pip install patch-manager
74
+
75
+ Optional features are available as extras::
76
+
77
+ pip install patch-manager[gmail] # send/fetch review mail via Gmail
78
+ pip install patch-manager[review] # AI-assisted patch review
79
+ pip install patch-manager[all] # everything
80
+
81
+ The ``patman`` command is then on your path.
82
+
83
+ Quick start
84
+ -----------
85
+
86
+ From a git branch containing the commits you want to send::
87
+
88
+ patman # create, check and email the series
89
+ patman -n # dry run: create and check, but do not send
90
+
91
+ See ``patman --full-help`` for the complete manual, or the documentation
92
+ linked below.
93
+
94
+ Documentation
95
+ -------------
96
+
97
+ Full documentation is hosted on Read the Docs:
98
+
99
+ https://patman.readthedocs.io/
100
+
101
+ Development
102
+ -----------
103
+
104
+ Run the test suite from a checkout::
105
+
106
+ pip install -r requirements.txt
107
+ pip install -e .
108
+ patman test
109
+
110
+ The suite is self-contained: a pinned ``checkpatch.pl`` and its helper files
111
+ live in ``scripts/``, and the bundled ``u_boot_pylib`` package is vendored in
112
+ the tree, so no surrounding U-Boot source is required.
113
+
114
+ License
115
+ -------
116
+
117
+ GPL-2.0-or-later. See the ``LICENSE`` file for the full text.
@@ -0,0 +1,54 @@
1
+ LICENSE
2
+ README.rst
3
+ pyproject.toml
4
+ patch_manager.egg-info/PKG-INFO
5
+ patch_manager.egg-info/SOURCES.txt
6
+ patch_manager.egg-info/dependency_links.txt
7
+ patch_manager.egg-info/entry_points.txt
8
+ patch_manager.egg-info/requires.txt
9
+ patch_manager.egg-info/top_level.txt
10
+ patman/__init__.py
11
+ patman/__main__.py
12
+ patman/checkpatch.py
13
+ patman/cmdline.py
14
+ patman/commit.py
15
+ patman/control.py
16
+ patman/cser_helper.py
17
+ patman/cseries.py
18
+ patman/database.py
19
+ patman/func_test.py
20
+ patman/get_maintainer.py
21
+ patman/gmail.py
22
+ patman/patchstream.py
23
+ patman/patchwork.py
24
+ patman/patman.rst
25
+ patman/project.py
26
+ patman/review.py
27
+ patman/send.py
28
+ patman/series.py
29
+ patman/settings.py
30
+ patman/status.py
31
+ patman/test_checkpatch.py
32
+ patman/test_common.py
33
+ patman/test_cseries.py
34
+ patman/test_settings.py
35
+ patman/workflow.py
36
+ patman/test/0000-cover-letter.patch
37
+ patman/test/0001-pci-Correct-cast-for-sandbox.patch
38
+ patman/test/0002-fdt-Correct-cast-for-sandbox-in-fdtdec_setup_mem_siz.patch
39
+ patman/test/get_maintainer
40
+ patman/test/maintainers
41
+ patman/test/test01.txt
42
+ u_boot_pylib/__init__.py
43
+ u_boot_pylib/__main__.py
44
+ u_boot_pylib/claude.py
45
+ u_boot_pylib/command.py
46
+ u_boot_pylib/cros_subprocess.py
47
+ u_boot_pylib/gitutil.py
48
+ u_boot_pylib/terminal.py
49
+ u_boot_pylib/test_claude.py
50
+ u_boot_pylib/test_command.py
51
+ u_boot_pylib/test_gitutil.py
52
+ u_boot_pylib/test_util.py
53
+ u_boot_pylib/tools.py
54
+ u_boot_pylib/tout.py
@@ -0,0 +1,20 @@
1
+ pygit2>=1.14
2
+ aiohttp>=3.9
3
+
4
+ [all]
5
+ google-api-python-client
6
+ google-auth-httplib2
7
+ google-auth-oauthlib
8
+ claude-agent-sdk
9
+ concurrencytest
10
+
11
+ [gmail]
12
+ google-api-python-client
13
+ google-auth-httplib2
14
+ google-auth-oauthlib
15
+
16
+ [review]
17
+ claude-agent-sdk
18
+
19
+ [test]
20
+ concurrencytest
@@ -0,0 +1,2 @@
1
+ patman
2
+ u_boot_pylib
@@ -3,6 +3,6 @@
3
3
  __all__ = [
4
4
  'checkpatch', 'cmdline', 'commit', 'control', 'cser_helper', 'cseries',
5
5
  'database', 'func_test', 'get_maintainer', '__main__', 'patchstream',
6
- 'patchwork', 'project', 'send', 'series', 'settings', 'setup', 'status',
6
+ 'patchwork', 'project', 'send', 'series', 'settings', 'status',
7
7
  'test_checkpatch', 'test_common', 'test_cseries', 'test_settings'
8
8
  ]
@@ -32,7 +32,7 @@ def run_patman():
32
32
  if not args.debug:
33
33
  sys.tracebacklimit = 0
34
34
 
35
- tout.init(tout.INFO if args.verbose else tout.WARNING)
35
+ tout.init(tout.INFO if args.verbose else tout.NOTICE)
36
36
 
37
37
  # Run our reasonably good tests
38
38
  if args.cmd == 'test':
@@ -40,13 +40,15 @@ def run_patman():
40
40
  from patman import func_test
41
41
  from patman import test_checkpatch
42
42
  from patman import test_cseries
43
+ from u_boot_pylib import test_command
43
44
 
44
45
  to_run = args.testname if args.testname not in [None, 'test'] else None
45
46
  result = test_util.run_test_suites(
46
47
  'patman', False, args.verbose, args.no_capture,
47
48
  args.test_preserve_dirs, None, to_run, None,
48
- [test_checkpatch.TestPatch, func_test.TestFunctional, 'settings',
49
- test_cseries.TestCseries])
49
+ [test_checkpatch.TestPatch, func_test.TestFunctional,
50
+ 'patman.settings', test_cseries.TestCseries,
51
+ test_command.TestRunInteractive])
50
52
  sys.exit(0 if result.wasSuccessful() else 1)
51
53
 
52
54
  # Process commits, produce patches files, check them, email them
@@ -92,8 +92,10 @@ def check_patch_parse_one_message(message):
92
92
  file_match = RE_FILE.search(message)
93
93
  # some messages have no file, catch those here
94
94
  no_file_match = any(s in message for s in [
95
- '\nSubject:', 'Missing Signed-off-by: line(s)',
96
- 'does MAINTAINERS need updating'
95
+ '\nSubject:', 'Missing Signed-off-by:',
96
+ 'does MAINTAINERS need updating',
97
+ 'email address mismatch',
98
+ 'should have a',
97
99
  ])
98
100
 
99
101
  if file_match:
@@ -157,9 +159,24 @@ def check_patch_parse(checkpatch_output, verbose=False):
157
159
  r' checks, (\d+)')
158
160
  re_ok = re.compile(r'.*has no obvious style problems')
159
161
  re_bad = re.compile(r'.*has style problems, please review')
160
-
161
- # A blank line indicates the end of a message
162
- for message in result.stdout.split('\n\n'):
162
+ # Patterns that start a new message block
163
+ re_message_start = re.compile(
164
+ r'^(ERROR|WARNING|CHECK):|^total:|^NOTE:|.* has (no obvious )?style')
165
+
166
+ # Split output into individual messages by looking for message-starting
167
+ # patterns at the start of lines, since messages may not be separated by
168
+ # blank lines
169
+ messages = []
170
+ current = []
171
+ for line in result.stdout.splitlines():
172
+ if re_message_start.match(line) and current:
173
+ messages.append('\n'.join(current))
174
+ current = []
175
+ current.append(line)
176
+ if current:
177
+ messages.append('\n'.join(current))
178
+
179
+ for message in messages:
163
180
  if verbose:
164
181
  print(message)
165
182