From 19fc89840fdfc2ce634b8c57a643e8dd58762f11 Mon Sep 17 00:00:00 2001 From: dmiller Date: Mon, 29 Jan 2024 17:09:26 +0000 Subject: [PATCH] Convert ndiff and zenmap to setuptools. Fixes #2649 --- ndiff/setup.py | 59 ++++++++------------ zenmap/README | 2 +- zenmap/install_scripts/macosx/make-bundle.sh | 2 +- zenmap/setup.py | 30 +++++----- 4 files changed, 41 insertions(+), 52 deletions(-) diff --git a/ndiff/setup.py b/ndiff/setup.py index af2b6127d..c163ae089 100644 --- a/ndiff/setup.py +++ b/ndiff/setup.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 import errno import sys @@ -8,13 +8,9 @@ import re from stat import ST_MODE -import distutils.command -import distutils.command.install -import distutils.core -import distutils.cmd -import distutils.errors -from distutils import log -from distutils.command.install import install +import setuptools.command.install +from setuptools import setup, Command +import logging APP_NAME = "ndiff" # The name of the file used to record the list of installed files, so that the @@ -61,10 +57,10 @@ def path_strip_prefix(path, prefix): ############################################################################### -# Distutils subclasses +# setuptools subclasses -class null_command(distutils.cmd.Command): - """This is a dummy distutils command that does nothing. We use it to +class null_command(Command): + """This is a dummy setuptools command that does nothing. We use it to replace the install_egg_info and avoid installing a .egg-info file, because there's no option to disable that.""" def initialize_options(self): @@ -80,11 +76,7 @@ class null_command(distutils.cmd.Command): pass -class checked_install(distutils.command.install.install): - """This is a wrapper around the install command that checks for an error - caused by not having the python-dev package installed. By default, - distutils gives a misleading error message: "invalid Python installation." - """ +class checked_install(setuptools.command.install.install): def finalize_options(self): # Ubuntu's python2.6-2.6.4-0ubuntu3 package changes sys.prefix in @@ -92,15 +84,11 @@ class checked_install(distutils.command.install.install): # default). Because we need the unchanged value later, remember it # here. self.saved_prefix = sys.prefix - try: - distutils.command.install.install.finalize_options(self) - except distutils.errors.DistutilsPlatformError as e: - raise distutils.errors.DistutilsPlatformError(str(e) + """ -Installing your distribution's python-dev package may solve this problem.""") + super().finalize_options() def set_modules_path(self): app_file_name = os.path.join(self.install_scripts, APP_NAME) - # Find where the modules are installed. distutils will put them in + # Find where the modules are installed. setuptools will put them in # self.install_lib, but that path can contain the root (DESTDIR), so we # must strip it off if necessary. modules_dir = self.install_lib @@ -124,7 +112,7 @@ Installing your distribution's python-dev package may solve this problem.""") app_file.close() def run(self): - install.run(self) + super().run() # These below are from Zenmap. We're only using set_modules_path right now, but # we might consider whether the others would be useful (or, if not, whether we @@ -138,7 +126,7 @@ Installing your distribution's python-dev package may solve this problem.""") def get_installed_files(self): """Return a list of installed files and directories, each prefixed with the installation root if given. The list of installed directories - doesn't come from distutils so it may be incomplete.""" + doesn't come from setuptools so it may be incomplete.""" installed_files = self.get_outputs() for package in self.distribution.py_modules: dir = package.replace(".", "/") @@ -236,7 +224,7 @@ for dir in dirs: doesn't strip off the installation root, if any. File names containing newline characters are not handled.""" if INSTALLED_FILES_NAME == self.record: - distutils.log.warn("warning: installation record is overwriting " + logging.warning("warning: installation record is overwriting " "--record file '%s'." % self.record) with open(INSTALLED_FILES_NAME, "w") as f: for output in self.get_installed_files(): @@ -244,8 +232,8 @@ for dir in dirs: print(output, file=f) -class my_uninstall(distutils.cmd.Command): - """A distutils command that performs uninstallation. It reads the list of +class my_uninstall(Command): + """A setuptools command that performs uninstallation. It reads the list of installed files written by the install command.""" command_name = "uninstall" @@ -265,8 +253,8 @@ class my_uninstall(distutils.cmd.Command): f = open(INSTALLED_FILES_NAME, "r") except IOError as e: if e.errno == errno.ENOENT: - log.error("Couldn't open the installation record '%s'. " - "Have you installed yet?" % INSTALLED_FILES_NAME) + logging.error("Couldn't open the installation record '%s'. " + "Have you installed yet?", INSTALLED_FILES_NAME) return installed_files = [file.rstrip("\n") for file in f.readlines()] f.close() @@ -282,29 +270,30 @@ class my_uninstall(distutils.cmd.Command): dirs.append(path) # Delete the files. for file in files: - log.info("Removing '%s'." % file) + logging.info("Removing '%s'.", file) try: if not self.dry_run: os.remove(file) except OSError as e: - log.error(str(e)) + logging.error(str(e)) # Delete the directories. First reverse-sort the normalized paths by # length so that child directories are deleted before their parents. dirs = [os.path.normpath(dir) for dir in dirs] dirs.sort(key=len, reverse=True) for dir in dirs: try: - log.info("Removing the directory '%s'." % dir) + logging.info("Removing the directory '%s'.", dir) if not self.dry_run: os.rmdir(dir) except OSError as e: if e.errno == errno.ENOTEMPTY: - log.info("Directory '%s' not empty; not removing." % dir) + logging.info("Directory '%s' not empty; not removing.", + dir) else: - log.error(str(e)) + logging.error(str(e)) -distutils.core.setup(name="ndiff", scripts=["scripts/ndiff"], +setup(name="ndiff", scripts=["scripts/ndiff"], py_modules=["ndiff"], data_files=[("share/man/man1", ["docs/ndiff.1"])], cmdclass={ diff --git a/zenmap/README b/zenmap/README index 26aef5c1d..fc5bddf9b 100644 --- a/zenmap/README +++ b/zenmap/README @@ -45,7 +45,7 @@ Default (source) Installation * Double click the zenmap file * Call the Python interpreter on the zenmap file - Zenmap is packaged using Python distutils. To install Zenmap + Zenmap is packaged using Python setuptools. To install Zenmap independently of Nmap, enter the zenmap subdirectory and run python setup.py install diff --git a/zenmap/install_scripts/macosx/make-bundle.sh b/zenmap/install_scripts/macosx/make-bundle.sh index 7f37d05c4..d866d603c 100755 --- a/zenmap/install_scripts/macosx/make-bundle.sh +++ b/zenmap/install_scripts/macosx/make-bundle.sh @@ -78,7 +78,7 @@ done python -m compileall "$PYTHONLIB"/site-packages #|| true echo "Stripping unoptimized Python libraries" -echo "Building using distutils" +echo "Building using setuptools" python3 setup.py build --executable "/usr/bin/env python3" python3 setup.py install vanilla --prefix "$BASE/Resources" diff --git a/zenmap/setup.py b/zenmap/setup.py index 97e9ef6cc..3ce59b9f6 100755 --- a/zenmap/setup.py +++ b/zenmap/setup.py @@ -64,10 +64,9 @@ import os import os.path import re -import distutils.sysconfig -from distutils import log -from distutils.core import setup, Command -from distutils.command.install import install +import logging +from setuptools import setup, Command +from setuptools.command.install import install from glob import glob from stat import S_IRGRP, S_IROTH, S_IRUSR, S_IRWXU, S_IWUSR, S_IXGRP, S_IXOTH, ST_MODE @@ -189,7 +188,7 @@ class my_install(install): def get_installed_files(self): """Return a list of installed files and directories, each prefixed with the installation root if given. The list of installed directories - doesn't come from distutils so it may be incomplete.""" + doesn't come from setuptools so it may be incomplete.""" installed_files = self.get_outputs() for package in self.distribution.packages: dir = package.replace(".", "/") @@ -290,7 +289,7 @@ for dir in dirs: def set_modules_path(self): app_file_name = os.path.join(self.install_scripts, APP_NAME) - # Find where the modules are installed. distutils will put them in + # Find where the modules are installed. setuptools will put them in # self.install_lib, but that path can contain the root (DESTDIR), so we # must strip it off if necessary. modules_dir = self.install_lib @@ -412,7 +411,7 @@ for dir in dirs: doesn't strip off the installation root, if any. File names containing newline characters are not handled.""" if INSTALLED_FILES_NAME == self.record: - distutils.log.warn("warning: installation record is overwriting " + logging.warning("warning: installation record is overwriting " "--record file '%s'." % self.record) with open(INSTALLED_FILES_NAME, "w") as f: for output in self.get_installed_files(): @@ -421,7 +420,7 @@ for dir in dirs: class my_uninstall(Command): - """A distutils command that performs uninstallation. It reads the list of + """A setuptools command that performs uninstallation. It reads the list of installed files written by the install command.""" command_name = "uninstall" @@ -441,8 +440,8 @@ class my_uninstall(Command): f = open(INSTALLED_FILES_NAME, "r") except IOError as e: if e.errno == errno.ENOENT: - log.error("Couldn't open the installation record '%s'. " - "Have you installed yet?" % INSTALLED_FILES_NAME) + logging.error("Couldn't open the installation record '%s'. " + "Have you installed yet?", INSTALLED_FILES_NAME) return installed_files = [file.rstrip("\n") for file in f.readlines()] f.close() @@ -458,26 +457,27 @@ class my_uninstall(Command): dirs.append(path) # Delete the files. for file in files: - log.info("Removing '%s'." % file) + logging.info("Removing '%s'.", file) try: if not self.dry_run: os.remove(file) except OSError as e: - log.error(str(e)) + logging.error(str(e)) # Delete the directories. First reverse-sort the normalized paths by # length so that child directories are deleted before their parents. dirs = [os.path.normpath(dir) for dir in dirs] dirs.sort(key=len, reverse=True) for dir in dirs: try: - log.info("Removing the directory '%s'." % dir) + logging.info("Removing the directory '%s'.", dir) if not self.dry_run: os.rmdir(dir) except OSError as e: if e.errno == errno.ENOTEMPTY: - log.info("Directory '%s' not empty; not removing." % dir) + logging.info("Directory '%s' not empty; not removing.", + dir) else: - log.error(str(e)) + logging.error(str(e)) # setup can be called in different ways depending on what we're doing. (For # example py2exe needs special handling.) These arguments are common between