Unverified Kaydet (Commit) fe2d5bab authored tarafından Victor Stinner's avatar Victor Stinner Kaydeden (comit) GitHub

bpo-32159: Remove tools for CVS and Subversion (#4615)

CPython migrated from CVS to Subversion, to Mercurial, and then to
Git. CVS and Subversion are not more used to develop CPython.

* platform module: drop support for sys.subversion. The
  sys.subversion attribute has been removed in Python 3.3.
* Remove Misc/svnmap.txt
* Remove Tools/scripts/svneol.py
* Remove Tools/scripts/treesync.py
üst a4a3020a
...@@ -1202,9 +1202,6 @@ def _sys_version(sys_version=None): ...@@ -1202,9 +1202,6 @@ def _sys_version(sys_version=None):
_, branch, revision = sys._git _, branch, revision = sys._git
elif hasattr(sys, '_mercurial'): elif hasattr(sys, '_mercurial'):
_, branch, revision = sys._mercurial _, branch, revision = sys._mercurial
elif hasattr(sys, 'subversion'):
# sys.subversion was added in Python 2.5
_, branch, revision = sys.subversion
else: else:
branch = '' branch = ''
revision = '' revision = ''
...@@ -1259,7 +1256,7 @@ def python_branch(): ...@@ -1259,7 +1256,7 @@ def python_branch():
""" Returns a string identifying the Python implementation """ Returns a string identifying the Python implementation
branch. branch.
For CPython this is the Subversion branch from which the For CPython this is the SCM branch from which the
Python binary was built. Python binary was built.
If not available, an empty string is returned. If not available, an empty string is returned.
...@@ -1273,7 +1270,7 @@ def python_revision(): ...@@ -1273,7 +1270,7 @@ def python_revision():
""" Returns a string identifying the Python implementation """ Returns a string identifying the Python implementation
revision. revision.
For CPython this is the Subversion revision from which the For CPython this is the SCM revision from which the
Python binary was built. Python binary was built.
If not available, an empty string is returned. If not available, an empty string is returned.
......
...@@ -145,14 +145,14 @@ class PlatformTest(unittest.TestCase): ...@@ -145,14 +145,14 @@ class PlatformTest(unittest.TestCase):
("PyPy", "2.5.2", "trunk", "63378", ('63378', 'Mar 26 2009'), ("PyPy", "2.5.2", "trunk", "63378", ('63378', 'Mar 26 2009'),
"") "")
} }
for (version_tag, subversion, sys_platform), info in \ for (version_tag, scm, sys_platform), info in \
sys_versions.items(): sys_versions.items():
sys.version = version_tag sys.version = version_tag
if subversion is None: if scm is None:
if hasattr(sys, "_git"): if hasattr(sys, "_git"):
del sys._git del sys._git
else: else:
sys._git = subversion sys._git = scm
if sys_platform is not None: if sys_platform is not None:
sys.platform = sys_platform sys.platform = sys_platform
self.assertEqual(platform.python_implementation(), info[0]) self.assertEqual(platform.python_implementation(), info[0])
......
Remove CVS and Subversion tools: remove svneol.py and treesync.py scripts.
CPython migrated from CVS to Subversion, to Mercurial, and then to Git. CVS
and Subversion are no longer used to develop CPython.
...@@ -22,6 +22,5 @@ README.AIX Information about using Python on AIX ...@@ -22,6 +22,5 @@ README.AIX Information about using Python on AIX
README.coverity Information about running Coverity's Prevent on Python README.coverity Information about running Coverity's Prevent on Python
README.valgrind Information for Valgrind users, see valgrind-python.supp README.valgrind Information for Valgrind users, see valgrind-python.supp
SpecialBuilds.txt Describes extra symbols you can set for debug builds SpecialBuilds.txt Describes extra symbols you can set for debug builds
svnmap.txt Map of old SVN revs and branches to hg changeset ids
valgrind-python.supp Valgrind suppression file, see README.valgrind valgrind-python.supp Valgrind suppression file, see README.valgrind
vgrindefs Python configuration for vgrind (a generic pretty printer) vgrindefs Python configuration for vgrind (a generic pretty printer)
This diff is collapsed.
...@@ -61,9 +61,7 @@ rgrep.py Reverse grep through a file (useful for big logfiles) ...@@ -61,9 +61,7 @@ rgrep.py Reverse grep through a file (useful for big logfiles)
run_tests.py Run the test suite with more sensible default options run_tests.py Run the test suite with more sensible default options
serve.py Small wsgiref-based web server, used in make serve in Doc serve.py Small wsgiref-based web server, used in make serve in Doc
suff.py Sort a list of files by suffix suff.py Sort a list of files by suffix
svneol.py Set svn:eol-style on all files in directory
texi2html.py Convert GNU texinfo files into HTML texi2html.py Convert GNU texinfo files into HTML
treesync.py Synchronize source trees (very idiosyncratic)
untabify.py Replace tabs with spaces in argument files untabify.py Replace tabs with spaces in argument files
which.py Find a program in $PATH which.py Find a program in $PATH
win_add2path.py Add Python to the search path on Windows win_add2path.py Add Python to the search path on Windows
#! /usr/bin/env python3
r"""
SVN helper script.
Try to set the svn:eol-style property to "native" on every .py, .txt, .c and
.h file in the directory tree rooted at the current directory.
Files with the svn:eol-style property already set (to anything) are skipped.
svn will itself refuse to set this property on a file that's not under SVN
control, or that has a binary mime-type property set. This script inherits
that behavior, and passes on whatever warning message the failing "svn
propset" command produces.
In the Python project, it's safe to invoke this script from the root of
a checkout.
No output is produced for files that are ignored. For a file that gets
svn:eol-style set, output looks like:
property 'svn:eol-style' set on 'Lib\ctypes\__init__.py'
For a file not under version control:
svn: warning: 'patch-finalizer.txt' is not under version control
and for a file with a binary mime-type property:
svn: File 'Lib\test\test_pep263.py' has binary mime type property
"""
import re
import os
import sys
import subprocess
def propfiles(root, fn):
default = os.path.join(root, ".svn", "props", fn + ".svn-work")
try:
format = int(open(os.path.join(root, ".svn", "format")).read().strip())
except IOError:
return []
if format in (8, 9):
# In version 8 and 9, committed props are stored in prop-base, local
# modifications in props
return [os.path.join(root, ".svn", "prop-base", fn + ".svn-base"),
os.path.join(root, ".svn", "props", fn + ".svn-work")]
raise ValueError("Unknown repository format")
def proplist(root, fn):
"""Return a list of property names for file fn in directory root."""
result = []
for path in propfiles(root, fn):
try:
f = open(path)
except IOError:
# no properties file: not under version control,
# or no properties set
continue
while True:
# key-value pairs, of the form
# K <length>
# <keyname>NL
# V length
# <value>NL
# END
line = f.readline()
if line.startswith("END"):
break
assert line.startswith("K ")
L = int(line.split()[1])
key = f.read(L)
result.append(key)
f.readline()
line = f.readline()
assert line.startswith("V ")
L = int(line.split()[1])
value = f.read(L)
f.readline()
f.close()
return result
def set_eol_native(path):
cmd = 'svn propset svn:eol-style native "{}"'.format(path)
propset = subprocess.Popen(cmd, shell=True)
propset.wait()
possible_text_file = re.compile(r"\.([hc]|py|txt|sln|vcproj)$").search
def main():
for arg in sys.argv[1:] or [os.curdir]:
if os.path.isfile(arg):
root, fn = os.path.split(arg)
if 'svn:eol-style' not in proplist(root, fn):
set_eol_native(arg)
elif os.path.isdir(arg):
for root, dirs, files in os.walk(arg):
if '.svn' in dirs:
dirs.remove('.svn')
for fn in files:
if possible_text_file(fn):
if 'svn:eol-style' not in proplist(root, fn):
path = os.path.join(root, fn)
set_eol_native(path)
if __name__ == '__main__':
main()
#! /usr/bin/env python3
"""Script to synchronize two source trees.
Invoke with two arguments:
python treesync.py slave master
The assumption is that "master" contains CVS administration while
slave doesn't. All files in the slave tree that have a CVS/Entries
entry in the master tree are synchronized. This means:
If the files differ:
if the slave file is newer:
normalize the slave file
if the files still differ:
copy the slave to the master
else (the master is newer):
copy the master to the slave
normalizing the slave means replacing CRLF with LF when the master
doesn't use CRLF
"""
import os, sys, stat, getopt
# Interactivity options
default_answer = "ask"
create_files = "yes"
create_directories = "no"
write_slave = "ask"
write_master = "ask"
def main():
global default_answer, always_no, always_yes, create_files
global create_directories, write_master, write_slave
opts, args = getopt.getopt(sys.argv[1:], "nym:s:d:f:a:")
for o, a in opts:
if o == '-y':
default_answer = "yes"
if o == '-n':
default_answer = "no"
if o == '-s':
write_slave = a
if o == '-m':
write_master = a
if o == '-d':
create_directories = a
if o == '-f':
create_files = a
if o == '-a':
create_files = create_directories = write_slave = write_master = a
try:
[slave, master] = args
except ValueError:
print("usage: python", sys.argv[0] or "treesync.py", end=' ')
print("[-n] [-y] [-m y|n|a] [-s y|n|a] [-d y|n|a] [-f n|y|a]", end=' ')
print("slavedir masterdir")
return
process(slave, master)
def process(slave, master):
cvsdir = os.path.join(master, "CVS")
if not os.path.isdir(cvsdir):
print("skipping master subdirectory", master)
print("-- not under CVS")
return
print("-"*40)
print("slave ", slave)
print("master", master)
if not os.path.isdir(slave):
if not okay("create slave directory %s?" % slave,
answer=create_directories):
print("skipping master subdirectory", master)
print("-- no corresponding slave", slave)
return
print("creating slave directory", slave)
try:
os.mkdir(slave)
except OSError as msg:
print("can't make slave directory", slave, ":", msg)
return
else:
print("made slave directory", slave)
cvsdir = None
subdirs = []
names = os.listdir(master)
for name in names:
mastername = os.path.join(master, name)
slavename = os.path.join(slave, name)
if name == "CVS":
cvsdir = mastername
else:
if os.path.isdir(mastername) and not os.path.islink(mastername):
subdirs.append((slavename, mastername))
if cvsdir:
entries = os.path.join(cvsdir, "Entries")
for e in open(entries).readlines():
words = e.split('/')
if words[0] == '' and words[1:]:
name = words[1]
s = os.path.join(slave, name)
m = os.path.join(master, name)
compare(s, m)
for (s, m) in subdirs:
process(s, m)
def compare(slave, master):
try:
sf = open(slave, 'r')
except IOError:
sf = None
try:
mf = open(master, 'rb')
except IOError:
mf = None
if not sf:
if not mf:
print("Neither master nor slave exists", master)
return
print("Creating missing slave", slave)
copy(master, slave, answer=create_files)
return
if not mf:
print("Not updating missing master", master)
return
if sf and mf:
if identical(sf, mf):
return
sft = mtime(sf)
mft = mtime(mf)
if mft > sft:
# Master is newer -- copy master to slave
sf.close()
mf.close()
print("Master ", master)
print("is newer than slave", slave)
copy(master, slave, answer=write_slave)
return
# Slave is newer -- copy slave to master
print("Slave is", sft-mft, "seconds newer than master")
# But first check what to do about CRLF
mf.seek(0)
fun = funnychars(mf)
mf.close()
sf.close()
if fun:
print("***UPDATING MASTER (BINARY COPY)***")
copy(slave, master, "rb", answer=write_master)
else:
print("***UPDATING MASTER***")
copy(slave, master, "r", answer=write_master)
BUFSIZE = 16*1024
def identical(sf, mf):
while 1:
sd = sf.read(BUFSIZE)
md = mf.read(BUFSIZE)
if sd != md: return 0
if not sd: break
return 1
def mtime(f):
st = os.fstat(f.fileno())
return st[stat.ST_MTIME]
def funnychars(f):
while 1:
buf = f.read(BUFSIZE)
if not buf: break
if '\r' in buf or '\0' in buf: return 1
return 0
def copy(src, dst, rmode="rb", wmode="wb", answer='ask'):
print("copying", src)
print(" to", dst)
if not okay("okay to copy? ", answer):
return
f = open(src, rmode)
g = open(dst, wmode)
while 1:
buf = f.read(BUFSIZE)
if not buf: break
g.write(buf)
f.close()
g.close()
def raw_input(prompt):
sys.stdout.write(prompt)
sys.stdout.flush()
return sys.stdin.readline()
def okay(prompt, answer='ask'):
answer = answer.strip().lower()
if not answer or answer[0] not in 'ny':
answer = input(prompt)
answer = answer.strip().lower()
if not answer:
answer = default_answer
if answer[:1] == 'y':
return 1
if answer[:1] == 'n':
return 0
print("Yes or No please -- try again:")
return okay(prompt)
if __name__ == '__main__':
main()
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment