aboutsummaryrefslogtreecommitdiff
path: root/pw_status/py
diff options
context:
space:
mode:
authorWyatt Hepler <hepler@google.com>2020-09-25 08:14:20 -0700
committerWyatt Hepler <hepler@google.com>2020-09-25 23:08:32 +0000
commitde4bb2391a5e791b57735d1cee321265c113bd05 (patch)
tree73cd6558eab744b7b71a5b05eca7ebd434abb3e1 /pw_status/py
parent352fcbcf6131cc1aff40303554cb18ffe8ee2133 (diff)
downloadpigweed-de4bb2391a5e791b57735d1cee321265c113bd05.tar.gz
pw_status: Tool for migrating Status constants
update_style.py updates Status and StatusWithSize uses from Status::CODE to Status::Code() style. Change-Id: I81102b3e524c6a123845d2ee152310a7a2991f3d Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/19000 Reviewed-by: Keir Mierle <keir@google.com>
Diffstat (limited to 'pw_status/py')
-rwxr-xr-xpw_status/py/pw_status/update_style.py108
1 files changed, 108 insertions, 0 deletions
diff --git a/pw_status/py/pw_status/update_style.py b/pw_status/py/pw_status/update_style.py
new file mode 100755
index 000000000..d7b642ebf
--- /dev/null
+++ b/pw_status/py/pw_status/update_style.py
@@ -0,0 +1,108 @@
+#!/usr/bin/env python3
+# Copyright 2020 The Pigweed Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may not
+# use this file except in compliance with the License. You may obtain a copy of
+# the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations under
+# the License.
+"""Decodes and detokenizes Base64-encoded strings in serial output.
+
+The output is printed or saved to a file. Input is not supported.
+"""
+
+import argparse
+from pathlib import Path
+import re
+import sys
+from typing import Iterable
+
+from pw_presubmit import git_repo
+
+_REMAP = {
+ 'OK': 'Ok',
+ 'CANCELLED': 'Cancelled',
+ 'UNKNOWN': 'Unknown',
+ 'INVALID_ARGUMENT': 'InvalidArgument',
+ 'DEADLINE_EXCEEDED': 'DeadlineExceeded',
+ 'NOT_FOUND': 'NotFound',
+ 'ALREADY_EXISTS': 'AlreadyExists',
+ 'PERMISSION_DENIED': 'PermissionDenied',
+ 'UNAUTHENTICATED': 'Unauthenticated',
+ 'RESOURCE_EXHAUSTED': 'ResourceExhausted',
+ 'FAILED_PRECONDITION': 'FailedPrecondition',
+ 'ABORTED': 'Aborted',
+ 'OUT_OF_RANGE': 'OutOfRange',
+ 'UNIMPLEMENTED': 'Unimplemented',
+ 'INTERNAL': 'Internal',
+ 'UNAVAILABLE': 'Unavailable',
+ 'DATA_LOSS': 'DataLoss',
+}
+
+
+def _remap_status_with_size(match) -> str:
+ return f'StatusWithSize::{_REMAP[match.group(1)]}('
+
+
+def _remap_codes(match) -> str:
+ return f'{match.group(1)}::{_REMAP[match.group(2)]}()'
+
+
+_CODES = '|'.join(_REMAP.keys())
+
+_STATUS_WITH_SIZE_CTOR = re.compile(
+ fr'\bStatusWithSize\(Status::({_CODES}),\s*')
+_STATUS = re.compile(fr'\b(Status|StatusWithSize)::({_CODES})(?!")\b')
+
+
+def _parse_args():
+ """Parses and return command line arguments."""
+
+ parser = argparse.ArgumentParser(description=__doc__)
+ parser.add_argument('paths',
+ nargs='*',
+ type=Path,
+ help='Paths to repositories')
+ return parser.parse_args()
+
+
+def update_status(paths: Iterable[Path]) -> None:
+ if not paths:
+ paths = [Path.cwd()]
+
+ for path in paths:
+ if git_repo.has_uncommitted_changes(path):
+ raise RuntimeError('There are pending changes in the Git repo!')
+
+ updated = 0
+
+ for file in git_repo.list_files(pathspecs=('*.h', '*.cc', '*.cpp'),
+ repo_path=path):
+ orig = file.read_text()
+
+ # Replace StatusAWithSize constructor
+ text = _STATUS_WITH_SIZE_CTOR.sub(_remap_status_with_size, orig)
+
+ # Replace Status and StatusAWithSize
+ text = _STATUS.sub(_remap_codes, text)
+
+ if orig != text:
+ updated += 1
+ file.write_text(text)
+
+ print('Updated', updated, 'files.')
+ print('Manually inspect the changes! This script is not perfect.')
+
+
+def main():
+ return update_status(**vars(_parse_args()))
+
+
+if __name__ == '__main__':
+ sys.exit(main())