Explorar el Código

Merge pull request #8087 from ThomasWaldmann/less-setuppy-master

use less setup.py (master)
TW hace 1 año
padre
commit
77e13ad752

+ 1 - 1
Vagrantfile

@@ -200,7 +200,7 @@ def install_borg(fuse)
     pip install -U wheel  # upgrade wheel, might be too old
     cd borg
     pip install -r requirements.d/development.lock.txt
-    python setup.py clean clean2
+    python3 scripts/make.py clean
     pip install -e .[#{fuse}]
   EOF
 end

+ 8 - 4
docs/development.rst

@@ -360,8 +360,8 @@ for easier use by packagers downstream.
 When a command is added, a command line flag changed, added or removed,
 the usage docs need to be rebuilt as well::
 
-  python setup.py build_usage
-  python setup.py build_man
+  python scripts/make.py build_usage
+  python scripts/make.py build_man
 
 However, we prefer to do this as part of our :ref:`releasing`
 preparations, so it is generally not necessary to update these when
@@ -450,8 +450,12 @@ Checklist:
 - Update ``CHANGES.rst``, based on ``git log $PREVIOUS_RELEASE..``.
 - Check version number of upcoming release in ``CHANGES.rst``.
 - Render ``CHANGES.rst`` via ``make html`` and check for markup errors.
-- Verify that ``MANIFEST.in`` and ``setup.py`` are complete.
-- ``python setup.py build_usage ; python setup.py build_man`` and commit.
+- Verify that ``MANIFEST.in``, ``pyproject.toml`` and ``setup.py`` are complete.
+- Run these commands and commit::
+
+    python scripts/make.py build_usage
+    python scripts/make.py build_man
+
 - Tag the release::
 
     git tag -s -m "tagged/signed release X.Y.Z" X.Y.Z

+ 1 - 1
docs/installation.rst

@@ -179,7 +179,7 @@ following dependencies first:
 
   - Either pyfuse3_ (preferably, newer) or llfuse_ (older).
     See also the BORG_FUSE_IMPL env variable.
-  - See setup.py about the version requirements.
+  - See pyproject.toml about the version requirements.
 
 If you have troubles finding the right package names, have a look at the
 distribution specific sections below or the Vagrantfile in the git repository,

+ 1 - 0
docs/usage.rst

@@ -42,6 +42,7 @@ Usage
    usage/rcompress
    usage/rdelete
    usage/serve
+   usage/version
    usage/compact
    usage/config
    usage/lock

+ 2 - 3
docs/usage/mount.rst

@@ -48,6 +48,5 @@ borgfs
 .. Note::
 
     ``borgfs`` will be automatically provided if you used a distribution
-    package, ``pip`` or ``setup.py`` to install Borg. Users of the
-    standalone binary will have to create a symlink manually (see
-    :ref:`pyinstaller-binary`).
+    package or ``pip`` to install Borg. Users of the standalone binary will have
+    to manually create a symlink (see :ref:`pyinstaller-binary`).

+ 1 - 0
docs/usage/version.rst

@@ -0,0 +1 @@
+.. include:: version.rst.inc

+ 60 - 0
docs/usage/version.rst.inc

@@ -0,0 +1,60 @@
+.. IMPORTANT: this file is auto-generated from borg's built-in help, do not edit!
+
+.. _borg_version:
+
+borg version
+------------
+.. code-block:: none
+
+    borg [common options] version [options]
+
+.. only:: html
+
+    .. class:: borg-options-table
+
+    +-------------------------------------------------------+
+    | .. class:: borg-common-opt-ref                        |
+    |                                                       |
+    | :ref:`common_options`                                 |
+    +-------------------------------------------------------+
+
+    .. raw:: html
+
+        <script type='text/javascript'>
+        $(document).ready(function () {
+            $('.borg-options-table colgroup').remove();
+        })
+        </script>
+
+.. only:: latex
+
+
+
+    :ref:`common_options`
+        |
+
+Description
+~~~~~~~~~~~
+
+This command displays the borg client version / borg server version.
+
+If a local repo is given, the client code directly accesses the repository,
+thus we show the client version also as the server version.
+
+If a remote repo is given (e.g. ssh:), the remote borg is queried and
+its version is displayed as the server version.
+
+Examples::
+
+    # local repo (client uses 1.4.0 alpha version)
+    $ borg version /mnt/backup
+    1.4.0a / 1.4.0a
+
+    # remote repo (client uses 1.4.0 alpha, server uses 1.2.7 release)
+    $ borg version ssh://borg@borgbackup:repo
+    1.4.0a / 1.2.7
+
+Due to the version tuple format used in borg client/server negotiation, only
+a simplified version is displayed (as provided by borg.version.format_version).
+
+There is also borg --version to display a potentially more precise client version.

+ 1 - 1
pyproject.toml

@@ -124,7 +124,7 @@ dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$"
 # with existing code. if you want to change them, you should first fix all
 # ruff failures that appear with your change.
 [tool.ruff.per-file-ignores]
-"setup_docs.py" = ["E501"]
+"scripts/make.py" = ["E501"]
 "src/borg/archive.py" = ["E501"]
 "src/borg/archiver/help_cmd.py" = ["E501"]
 "src/borg/cache.py" = ["E501"]

+ 76 - 40
setup_docs.py → scripts/make.py

@@ -1,5 +1,6 @@
 # Support code for building docs (build_usage, build_man)
 
+import glob
 import os
 import io
 import re
@@ -9,22 +10,6 @@ from collections import OrderedDict
 from datetime import datetime, timezone
 import time
 
-from setuptools import Command
-
-
-def long_desc_from_readme():
-    with open("README.rst") as fd:
-        long_description = fd.read()
-        # remove header, but have one \n before first headline
-        start = long_description.find("What is BorgBackup?")
-        assert start >= 0
-        long_description = "\n" + long_description[start:]
-        # remove badges
-        long_description = re.compile(r"^\.\. start-badges.*^\.\. end-badges", re.M | re.S).sub("", long_description)
-        # remove unknown directives
-        long_description = re.compile(r"^\.\. highlight:: \w+$", re.M).sub("", long_description)
-        return long_description
-
 
 def format_metavar(option):
     if option.nargs in ("*", "..."):
@@ -37,16 +22,8 @@ def format_metavar(option):
         raise ValueError(f"Can't format metavar {option.metavar}, unknown nargs {option.nargs}!")
 
 
-class build_usage(Command):
-    description = "generate usage for each command"
-
-    user_options = [("output=", "O", "output directory")]
-
-    def initialize_options(self):
-        pass
-
-    def finalize_options(self):
-        pass
+class BuildUsage:
+    """generate usage docs for each command"""
 
     def run(self):
         print("generating usage docs")
@@ -63,6 +40,7 @@ class build_usage(Command):
         # borgfs_parser = Archiver(prog='borgfs').build_parser()
 
         self.generate_level("", parser, Archiver)
+        return 0
 
     def generate_level(self, prefix, parser, Archiver, extra_choices=None):
         is_subcommand = False
@@ -137,10 +115,6 @@ class build_usage(Command):
         # HTML output:
         # A table using some column-spans
 
-        def html_write(s):
-            for line in s.splitlines():
-                fp.write("    " + line + "\n")
-
         rows = []
         for group in parser._action_groups:
             if group.title == "Common options":
@@ -279,10 +253,8 @@ class build_usage(Command):
             fp.write(indent + option.ljust(padding) + desc + "\n")
 
 
-class build_man(Command):
-    description = "build man pages"
-
-    user_options = []
+class BuildMan:
+    """build man pages"""
 
     see_also = {
         "create": ("delete", "prune", "check", "patterns", "placeholders", "compression", "rcreate"),
@@ -322,12 +294,6 @@ class build_man(Command):
         "umount": "mount",
     }
 
-    def initialize_options(self):
-        pass
-
-    def finalize_options(self):
-        pass
-
     def run(self):
         print("building man pages (in docs/man)", file=sys.stderr)
         import borg
@@ -343,6 +309,7 @@ class build_man(Command):
         self.generate_level("", parser, Archiver, {"borgfs": borgfs_parser})
         self.build_topic_pages(Archiver)
         self.build_intro_page()
+        return 0
 
     def generate_level(self, prefix, parser, Archiver, extra_choices=None):
         is_subcommand = False
@@ -562,3 +529,72 @@ class build_man(Command):
 
         for option, desc in opts.items():
             write(option.ljust(padding), desc)
+
+
+cython_sources = """
+src/borg/compress.pyx
+src/borg/crypto/low_level.pyx
+src/borg/chunker.pyx
+src/borg/hashindex.pyx
+src/borg/item.pyx
+src/borg/checksums.pyx
+src/borg/platform/posix.pyx
+src/borg/platform/linux.pyx
+src/borg/platform/syncfilerange.pyx
+src/borg/platform/darwin.pyx
+src/borg/platform/freebsd.pyx
+src/borg/platform/windows.pyx
+""".strip().splitlines()
+
+
+def rm(file):
+    try:
+        os.unlink(file)
+    except FileNotFoundError:
+        return False
+    else:
+        return True
+
+
+class Clean:
+    def run(self):
+        for source in cython_sources:
+            genc = source.replace(".pyx", ".c")
+            rm(genc)
+            compiled_glob = source.replace(".pyx", ".cpython*")
+            for compiled in sorted(glob.glob(compiled_glob)):
+                rm(compiled)
+        return 0
+
+
+def usage():
+    print(
+        textwrap.dedent(
+            """
+        Usage:
+            python scripts/make.py clean        # clean workdir (remove generated files)
+            python scripts/make.py build_usage  # build usage documentation
+            python scripts/make.py build_man    # build man pages
+    """
+        )
+    )
+
+
+def main(argv):
+    if len(argv) < 2 or len(argv) == 2 and argv[1] in ("-h", "--help"):
+        usage()
+        return 0
+    command = argv[1]
+    if command == "clean":
+        return Clean().run()
+    if command == "build_usage":
+        return BuildUsage().run()
+    if command == "build_man":
+        return BuildMan().run()
+    usage()
+    return 1
+
+
+if __name__ == "__main__":
+    rc = main(sys.argv)
+    sys.exit(rc)

+ 19 - 38
setup.py

@@ -1,9 +1,9 @@
 # borgbackup - main setup code (see also setup.cfg and other setup_*.py files)
 
 import os
+import re
 import sys
 from collections import defaultdict
-from glob import glob
 
 try:
     import multiprocessing
@@ -11,7 +11,7 @@ except ImportError:
     multiprocessing = None
 
 from setuptools.command.build_ext import build_ext
-from setuptools import setup, Extension, Command
+from setuptools import setup, Extension
 from setuptools.command.sdist import sdist
 
 try:
@@ -20,7 +20,6 @@ except ImportError:
     cythonize = None
 
 sys.path += [os.path.dirname(__file__)]
-import setup_docs
 
 is_win32 = sys.platform.startswith("win32")
 is_openbsd = sys.platform.startswith("openbsd")
@@ -84,39 +83,7 @@ else:
         raise ImportError("The GIT version of Borg needs Cython. Install Cython or use a released version.")
 
 
-def rm(file):
-    try:
-        os.unlink(file)
-        print("rm", file)
-    except FileNotFoundError:
-        pass
-
-
-class Clean(Command):
-    user_options = []
-
-    def initialize_options(self):
-        pass
-
-    def finalize_options(self):
-        pass
-
-    def run(self):
-        for source in cython_sources:
-            genc = source.replace(".pyx", ".c")
-            rm(genc)
-            compiled_glob = source.replace(".pyx", ".cpython*")
-            for compiled in sorted(glob(compiled_glob)):
-                rm(compiled)
-
-
-cmdclass = {
-    "build_ext": build_ext,
-    "build_usage": setup_docs.build_usage,
-    "build_man": setup_docs.build_man,
-    "sdist": Sdist,
-    "clean2": Clean,
-}
+cmdclass = {"build_ext": build_ext, "sdist": Sdist}
 
 
 ext_modules = []
@@ -234,7 +201,7 @@ if not on_rtd:
     # this breaks chained commands like 'clean sdist'
     cythonizing = (
         len(sys.argv) > 1
-        and sys.argv[1] not in (("clean", "clean2", "egg_info", "--help-commands", "--version"))
+        and sys.argv[1] not in (("clean", "egg_info", "--help-commands", "--version"))
         and "--help" not in sys.argv[1:]
     )
 
@@ -253,4 +220,18 @@ if not on_rtd:
         ext_modules = cythonize(ext_modules, **cython_opts)
 
 
-setup(cmdclass=cmdclass, ext_modules=ext_modules, long_description=setup_docs.long_desc_from_readme())
+def long_desc_from_readme():
+    with open("README.rst") as fd:
+        long_description = fd.read()
+        # remove header, but have one \n before first headline
+        start = long_description.find("What is BorgBackup?")
+        assert start >= 0
+        long_description = "\n" + long_description[start:]
+        # remove badges
+        long_description = re.compile(r"^\.\. start-badges.*^\.\. end-badges", re.M | re.S).sub("", long_description)
+        # remove unknown directives
+        long_description = re.compile(r"^\.\. highlight:: \w+$", re.M).sub("", long_description)
+        return long_description
+
+
+setup(cmdclass=cmdclass, ext_modules=ext_modules, long_description=long_desc_from_readme())

+ 1 - 1
src/borg/archiver/__init__.py

@@ -501,7 +501,7 @@ class Archiver(
         self.prerun_checks(logger, is_serve)
         if not is_supported_msgpack():
             logger.error("You do not have a supported version of the msgpack python package installed. Terminating.")
-            logger.error("This should never happen as specific, supported versions are required by our setup.py.")
+            logger.error("This should never happen as specific, supported versions are required by our pyproject.toml.")
             logger.error("Do not contact borgbackup support about this.")
             return set_ec(EXIT_ERROR)
         if is_slow_msgpack():

+ 1 - 1
src/borg/helpers/msgpack.py

@@ -204,7 +204,7 @@ def is_slow_msgpack():
 
 
 def is_supported_msgpack():
-    # DO NOT CHANGE OR REMOVE! See also requirements and comments in setup.cfg.
+    # DO NOT CHANGE OR REMOVE! See also requirements and comments in pyproject.toml.
     import msgpack
 
     if msgpack.version in []:  # < add bad releases here to deny list