summaryrefslogtreecommitdiff
path: root/src/distutils2/command
diff options
context:
space:
mode:
Diffstat (limited to 'src/distutils2/command')
-rw-r--r--src/distutils2/command/install.py29
-rw-r--r--src/distutils2/command/install_distinfo.py174
-rw-r--r--src/distutils2/command/install_egg_info.py83
3 files changed, 200 insertions, 86 deletions
diff --git a/src/distutils2/command/install.py b/src/distutils2/command/install.py
index 588786f..4f0ccc3 100644
--- a/src/distutils2/command/install.py
+++ b/src/distutils2/command/install.py
@@ -79,15 +79,26 @@ class install(Command):
('record=', None,
"filename in which to record list of installed files"),
+
+ # .dist-info related arguments, read by install_dist_info
+ ('no-distinfo', None, 'do not create a .dist-info directory'),
+ ('distinfo-dir=', None,
+ 'directory where the the .dist-info directory will '
+ 'be installed'),
+ ('installer=', None, 'the name of the installer'),
+ ('requested', None, 'generate a REQUESTED file'),
+ ('no-requested', None, 'do not generate a REQUESTED file'),
+ ('no-distinfo-record', None, 'do not generate a RECORD file'),
]
- boolean_options = ['compile', 'force', 'skip-build']
+ boolean_options = ['compile', 'force', 'skip-build', 'no-dist-info',
+ 'requested', 'no-dist-record',]
user_options.append(('user', None,
"install in user site-package '%s'" % \
get_path('purelib', '%s_user' % os.name)))
boolean_options.append('user')
- negative_opt = {'no-compile' : 'compile'}
+ negative_opt = {'no-compile' : 'compile', 'no-requested': 'requested'}
def initialize_options(self):
@@ -159,6 +170,13 @@ class install(Command):
#self.install_info = None
self.record = None
+
+ # .dist-info related options
+ self.no_distinfo = None
+ self.distinfo_dir = None
+ self.installer = None
+ self.requested = None
+ self.no_distinfo_record = None
# -- Option finalizing methods -------------------------------------
@@ -305,6 +323,9 @@ class install(Command):
# Punt on doc directories for now -- after all, we're punting on
# documentation completely!
+
+ if self.no_distinfo is None:
+ self.no_distinfo = False
def dump_dirs(self, msg):
"""Dumps the list of user options."""
@@ -586,5 +607,7 @@ class install(Command):
('install_headers', has_headers),
('install_scripts', has_scripts),
('install_data', has_data),
- ('install_egg_info', lambda self:True),
+ # keep install_distinfo last, as it needs the record
+ # with files to be completely generated
+ ('install_distinfo', lambda self: not self.no_distinfo),
]
diff --git a/src/distutils2/command/install_distinfo.py b/src/distutils2/command/install_distinfo.py
new file mode 100644
index 0000000..e5b1665
--- /dev/null
+++ b/src/distutils2/command/install_distinfo.py
@@ -0,0 +1,174 @@
+"""
+distutils.command.install_distinfo
+==================================
+
+:Author: Josip Djolonga
+
+This module implements the ``install_distinfo`` command that creates the
+``.dist-info`` directory for the distribution, as specified in :pep:`376`.
+Usually, you do not have to call this command directly, it gets called
+automatically by the ``install`` command.
+"""
+
+from distutils2.command.cmd import Command
+from distutils2 import log
+from distutils2._backport.shutil import rmtree
+
+
+import csv
+import hashlib
+import os
+import re
+
+
+class install_distinfo(Command):
+ """Install a .dist-info directory for the package"""
+
+ description = 'Install a .dist-info directory for the package'
+
+ user_options = [
+ ('dist-info-dir=', None,
+ 'directory where the the .dist-info directory will '
+ 'be installed'),
+ ('installer=', None, 'the name of the installer'),
+ ('requested', None, 'generate a REQUESTED file'),
+ ('no-requested', None, 'do not generate a REQUESTED file'),
+ ('no-dist-record', None, 'do not generate a RECORD file'),
+ ]
+
+ boolean_options = [
+ 'requested',
+ 'no-dist-record',
+ ]
+
+ negative_opt = {'no-requested': 'requested'}
+
+ def initialize_options(self):
+ self.distinfo_dir = None
+ self.installer = None
+ self.requested = None
+ self.no_distinfo_record = None
+
+ def finalize_options(self):
+ self.set_undefined_options('install',
+ ('distinfo_dir', 'distinfo_dir'),
+ ('installer', 'installer'),
+ ('requested', 'requested'),
+ ('no_distinfo_record',
+ 'no_distinfo_record'))
+
+ self.set_undefined_options('install_lib',
+ ('install_dir', 'distinfo_dir'))
+
+ if self.installer is None:
+ self.installer = 'distutils'
+ if self.requested is None:
+ self.requested = True
+ if self.no_distinfo_record is None:
+ self.no_distinfo_record = False
+
+ metadata = self.distribution.metadata
+
+ basename = "%s-%s.dist-info" % (
+ to_filename(safe_name(metadata['Name'])),
+ to_filename(safe_version(metadata['Version'])),
+ )
+
+ self.distinfo_dir = os.path.join(self.distinfo_dir, basename)
+ self.outputs = []
+
+ def run(self):
+ if not self.dry_run:
+ target = self.distinfo_dir
+
+ if os.path.isdir(target) and not os.path.islink(target):
+ rmtree(target)
+ elif os.path.exists(target):
+ self.execute(os.unlink, (self.distinfo_dir,),
+ "Removing " + target)
+
+ self.execute(os.makedirs, (target,), "Creating " + target)
+
+ metadata_path = os.path.join(self.distinfo_dir, 'METADATA')
+ log.info('Creating %s' % (metadata_path,))
+ self.distribution.metadata.write(metadata_path)
+ self.outputs.append(metadata_path)
+
+ installer_path = os.path.join(self.distinfo_dir, 'INSTALLER')
+ log.info('Creating %s' % (installer_path,))
+ f = open(installer_path, 'w')
+ try:
+ f.write(self.installer)
+ finally:
+ f.close()
+ self.outputs.append(installer_path)
+
+ if self.requested:
+ requested_path = os.path.join(self.distinfo_dir, 'REQUESTED')
+ log.info('Creating %s' % (requested_path,))
+ f = open(requested_path, 'w')
+ f.close()
+ self.outputs.append(requested_path)
+
+ if not self.no_distinfo_record:
+ record_path = os.path.join(self.distinfo_dir, 'RECORD')
+ log.info('Creating %s' % (record_path,))
+ f = open(record_path, 'wb')
+ try:
+ writer = csv.writer(f, delimiter=',',
+ lineterminator=os.linesep,
+ quotechar='"')
+
+ install = self.get_finalized_command('install')
+
+ for fpath in install.get_outputs():
+ if fpath.endswith('.pyc') or fpath.endswith('.pyo'):
+ # do not put size and md5 hash, as in PEP-376
+ writer.writerow((fpath, '', ''))
+ else:
+ size = os.path.getsize(fpath)
+ fd = open(fpath, 'r')
+ hash = hashlib.md5()
+ hash.update(fd.read())
+ md5sum = hash.hexdigest()
+ writer.writerow((fpath, md5sum, size))
+
+ # add the RECORD file itself
+ writer.writerow((record_path, '', ''))
+ self.outputs.append(record_path)
+ finally:
+ f.close()
+
+ def get_outputs(self):
+ return self.outputs
+
+
+# The following routines are taken from setuptools' pkg_resources module and
+# can be replaced by importing them from pkg_resources once it is included
+# in the stdlib.
+
+
+def safe_name(name):
+ """Convert an arbitrary string to a standard distribution name
+
+ Any runs of non-alphanumeric/. characters are replaced with a single '-'.
+ """
+ return re.sub('[^A-Za-z0-9.]+', '-', name)
+
+
+def safe_version(version):
+ """Convert an arbitrary string to a standard version string
+
+ Spaces become dots, and all other non-alphanumeric characters become
+ dashes, with runs of multiple dashes condensed to a single dash.
+ """
+ version = version.replace(' ', '.')
+ return re.sub('[^A-Za-z0-9.]+', '-', version)
+
+
+def to_filename(name):
+ """Convert a project or version name to its filename-escaped form
+
+ Any '-' characters are currently replaced with '_'.
+ """
+ return name.replace('-', '_')
diff --git a/src/distutils2/command/install_egg_info.py b/src/distutils2/command/install_egg_info.py
deleted file mode 100644
index c8b568a..0000000
--- a/src/distutils2/command/install_egg_info.py
+++ /dev/null
@@ -1,83 +0,0 @@
-"""distutils.command.install_egg_info
-
-Implements the Distutils 'install_egg_info' command, for installing
-a package's PKG-INFO metadata."""
-
-
-from distutils2.command.cmd import Command
-from distutils2 import log
-from distutils2._backport.shutil import rmtree
-import os, sys, re
-
-class install_egg_info(Command):
- """Install an .egg-info file for the package"""
-
- description = "Install package's PKG-INFO metadata as an .egg-info file"
- user_options = [
- ('install-dir=', 'd', "directory to install to"),
- ]
-
- def initialize_options(self):
- self.install_dir = None
-
- def finalize_options(self):
- metadata = self.distribution.metadata
- self.set_undefined_options('install_lib',('install_dir','install_dir'))
- basename = "%s-%s-py%s.egg-info" % (
- to_filename(safe_name(metadata['Name'])),
- to_filename(safe_version(metadata['Version'])),
- sys.version[:3]
- )
- self.target = os.path.join(self.install_dir, basename)
- self.outputs = [self.target]
-
- def run(self):
- target = self.target
- if os.path.isdir(target) and not os.path.islink(target):
- if self.dry_run:
- pass # XXX
- else:
- rmtree(target)
- elif os.path.exists(target):
- self.execute(os.unlink,(self.target,),"Removing "+target)
- elif not os.path.isdir(self.install_dir):
- self.execute(os.makedirs, (self.install_dir,),
- "Creating "+self.install_dir)
- log.info("Writing %s", target)
- if not self.dry_run:
- f = open(target, 'w')
- self.distribution.metadata.write_file(f)
- f.close()
-
- def get_outputs(self):
- return self.outputs
-
-
-# The following routines are taken from setuptools' pkg_resources module and
-# can be replaced by importing them from pkg_resources once it is included
-# in the stdlib.
-
-def safe_name(name):
- """Convert an arbitrary string to a standard distribution name
-
- Any runs of non-alphanumeric/. characters are replaced with a single '-'.
- """
- return re.sub('[^A-Za-z0-9.]+', '-', name)
-
-
-def safe_version(version):
- """Convert an arbitrary string to a standard version string
-
- Spaces become dots, and all other non-alphanumeric characters become
- dashes, with runs of multiple dashes condensed to a single dash.
- """
- version = version.replace(' ','.')
- return re.sub('[^A-Za-z0-9.]+', '-', version)
-
-
-def to_filename(name):
- """Convert a project or version name to its filename-escaped form
-
- Any '-' characters are currently replaced with '_'.
- """
- return name.replace('-','_')