Continue migrating functionality from backport.pl to backport.py
* tools/dist/nominate-backport.py
(subprocess_output): Remove local function affecting...
(check_local_mods_to_STATUS),
(get_availid),
(main): ... these functions, replacing with a call to
backport.merger.run_svn() or one of its close friends.
(main): Moving local code figuring out some wc data from here...
* backport/wc.py
(get_wc_info): ... to here to enable future re-use (parsing additional
data at the same time).
git-svn-id: https://svn.apache.org/repos/asf/subversion/trunk@1925156 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/tools/dist/backport/wc.py b/tools/dist/backport/wc.py
new file mode 100644
index 0000000..adb09bd
--- /dev/null
+++ b/tools/dist/backport/wc.py
@@ -0,0 +1,65 @@
+#!/usr/bin/env python3
+
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you 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
+#
+# http://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.
+
+"""
+backport.wc - library for performing actions on the current WC
+"""
+
+import backport.merger
+
+import logging
+
+logger = logging.getLogger(__name__)
+
+
+def get_wc_info():
+ """Run svn info. Return a dictionary with the following elements:
+ URL: The WC url
+ BASE_revision: The WC base revision
+ Repository_root: The WC repository root
+ """
+ (exit_code, stdout, stderr) = backport.merger.run_svn(["info"])
+ URL = ""
+ BASE_revision = ""
+ Repository_root = ""
+ for line in stdout.split('\n'):
+ if line.startswith('URL:'):
+ URL = line.split('URL:')[1].strip()
+ elif line.startswith('Revision:'):
+ BASE_revision = line.split('Revision:')[1].strip()
+ elif line.startswith('Repository Root:'):
+ Repository_root = line.split('Repository Root:')[1].strip()
+ return {"URL": URL,
+ "BASE_revision": BASE_revision,
+ "Repository_root": Repository_root,
+ }
+
+
+def setUpModule():
+ "Set-up function, invoked by 'python -m unittest'."
+ # Suppress warnings generated by the test data.
+ # TODO: some test functions assume .assertLogs is available, they fail with
+ # AttributeError if it's absent (e.g., on python < 3.4).
+ try:
+ unittest.TestCase.assertLogs
+ except AttributeError:
+ logger.setLevel(logging.ERROR)
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/tools/dist/nominate-backport.py b/tools/dist/nominate-backport.py
index 95a0735..c21db19 100755
--- a/tools/dist/nominate-backport.py
+++ b/tools/dist/nominate-backport.py
@@ -44,12 +44,8 @@
STATUS = './STATUS'
LINELENGTH = 79
-def subprocess_output(args):
- result = subprocess.run(args, capture_output = True, text = True)
- return result.stdout
-
def check_local_mods_to_STATUS():
- status = subprocess_output(['svn', 'diff', './STATUS'])
+ (exit_code, status, stderr) = backport.merger.run_svn(['diff', './STATUS'])
if status != "":
print(f"Local mods to STATUS file {STATUS}")
print(status)
@@ -72,7 +68,7 @@
except KeyError:
try:
# Failing, try executing svn auth
- auth = subprocess_output(['svn', 'auth', 'svn.apache.org:443'])
+ (exitcode, auth, stderr) = backport.merger.run_svn(['auth', 'svn.apache.org:443'])
correct_realm = False
for line in auth.split('\n'):
line = line.strip()
@@ -154,18 +150,11 @@
justification = sys.argv[2]
# Get some WC info
- info = subprocess_output(['svn', 'info'])
- BASE_revision = ""
- URL = ""
- for line in info.split('\n'):
- if line.startswith('URL:'):
- URL = line.split('URL:')[1]
- elif line.startswith('Revision:'):
- BASE_revision = line.split('Revision:')[1]
+ wcinfo = backport.wc.get_wc_info()
# To save typing, require just the last three digits if they're unambiguous.
- if BASE_revision != "":
- BASE_revision = int(BASE_revision)
+ if wcinfo["BASE_revision"] != "":
+ BASE_revision = int(wcinfo["BASE_revision"])
if BASE_revision > 1000:
residue = BASE_revision % 1000
thousands = BASE_revision - residue
@@ -176,12 +165,13 @@
revisions.sort()
# Determine whether a backport branch exists
- branch = subprocess_output(['svn', 'info', '--show-item', 'url', '--', URL+'-r'+str(revisions[0])]).replace('\n', '')
+ (exit_code, branch, stderr) = backport.merger.run_svn(['info', '--show-item', 'url', '--',
+ wcinfo["URL"] + '-r'+str(revisions[0])]).replace('\n', '')
if branch == "":
branch = None
# Get log message from first revision
- logmsg = subprocess_output(['svn', 'propget', '--revprop', '-r',
+ (exit_code, logmsg, stderr) = backport.merger.run_svn(['propget', '--revprop', '-r',
str(revisions[0]), '--strict', 'svn:log', '^/'])
if (logmsg == ""):
print("Can't fetch log message of r" + revisions[0])
@@ -225,17 +215,17 @@
sf.unparse(f)
# Check for changes to commit
- diff = subprocess_output(['svn', 'diff', STATUS])
+ (exit_code, diff , stderr) = backport.merger.run_svn(['diff', STATUS])
print(diff)
answer = input("Commit this nomination [y/N]? ")
if answer.lower() == "y":
- subprocess_output(['svn', 'commit', STATUS, '-m',
+ backport.merger.run_svn_quiet(['commit', STATUS, '-m',
'* STATUS: Nominate r' +
', r'.join(map(str, revisions))])
else:
answer = input("Revert STATUS (destroying local mods) [y/N]? ")
if answer.lower() == "y":
- subprocess_output(['svn', 'revert', STATUS])
+ backport.merger.run_svn_quiet(['revert', STATUS])
sys.exit(0)