Generate metadata as python module.

This commit is contained in:
Bastian Kleineidam 2013-04-08 20:12:50 +02:00
parent e5a4d8b317
commit d0540bb7a7
6 changed files with 158 additions and 12 deletions

1
.gitignore vendored
View File

@ -9,3 +9,4 @@ Changelog.patool*
/doc/README.md
/testresults.txt
/tests/__pycache__
/_Patool_configdata.py

View File

@ -105,7 +105,10 @@ clean:
find . -name \*.pyo -delete
rm -rf build dist
test:
localbuild:
$(PYTHON) setup.py build
test: localbuild
$(PYTHON) -m pytest $(PYTESTOPTS) $(TESTOPTS) $(TESTS)
doc/$(LAPPNAME).txt: doc/$(LAPPNAME).1
@ -135,5 +138,6 @@ changelog:
# closes issues mentioned in the changelog entries.
github-changelog $(DRYRUN) $(GITUSER) $(GITREPO) doc/changelog.txt
.PHONY: changelog update-copyright deb test clean count pyflakes check app
.PHONY: changelog update-copyright deb test clean count pyflakes check
.PHONY: releasecheck release upload sign dist all tag register homepage
.PHONY: localbuild doccheck

4
patool
View File

@ -22,8 +22,8 @@ import sys
import argparse
import pydoc
import patoolib
from patoolib.util import log_error, log_internal_error, PatoolError, App
from patoolib.util import log_error, log_internal_error, PatoolError
from patoolib.configuration import App
def run_extract(args):
"""Extract files from archive(s)."""

16
patoolib/configuration.py Normal file
View File

@ -0,0 +1,16 @@
# Copyright (C) 2013 Bastian Kleineidam
"""
Define basic configuration data like version or application name.
"""
import _Patool_configdata as configdata
Version = configdata.version
ReleaseDate = configdata.release_date
AppName = configdata.name
App = AppName+u" "+Version
Author = configdata.author
Maintainer = configdata.maintainer
Copyright = u"Copyright (C) 2004-2008 " + Author
Url = configdata.url
SupportUrl = Url + u"issues"
Email = configdata.author_email

View File

@ -23,6 +23,7 @@ import mimetypes
import tempfile
import time
import traceback
from . import configuration
try:
from shutil import which
except ImportError:
@ -79,10 +80,6 @@ except ImportError:
return None
AppName = "patool"
App = "%s 1.1" % AppName
SupportUrl = "https://github.com/wummel/patool/issues"
# internal MIME database
mimedb = None
@ -471,7 +468,7 @@ at %(url)s and include at least the information below:
Not disclosing some of the information below due to privacy reasons is ok.
I will try to help you nonetheless, but you have to give me something
I can work with ;) .
""" % dict(app=AppName, url=SupportUrl), file=out)
""" % dict(app=configuration.AppName, url=configuration.SupportUrl), file=out)
if etype is None:
etype = sys.exc_info()[0]
if evalue is None:
@ -483,7 +480,7 @@ I can work with ;) .
print_app_info(out=out)
print_locale_info(out=out)
print(os.linesep,
"******** %s internal error, over and out ********" % AppName, file=out)
"******** %s internal error, over and out ********" % configuration.AppName, file=out)
def print_env_info(key, out=sys.stderr):
"""If given environment key is defined, print it out."""
@ -501,7 +498,7 @@ def print_locale_info(out=sys.stderr):
def print_app_info(out=sys.stderr):
"""Print system and application info (output defaults to stderr)."""
print("System info:", file=out)
print(App, file=out)
print(configuration.App, file=out)
print("Python %(version)s on %(platform)s" %
{"version": sys.version, "platform": sys.platform}, file=out)
stime = strtime(time.time())

130
setup.py
View File

@ -22,6 +22,7 @@ import sys
if not hasattr(sys, "version_info") or sys.version_info < (2, 7, 0, "final", 0):
raise SystemExit("This program requires Python 2.7 or later.")
import os
import re
import shutil
import glob
import subprocess
@ -29,7 +30,6 @@ try:
from cx_Freeze import setup, Executable
except ImportError:
from distutils.core import setup
from distutils.command.register import register
try:
# py2exe monkey-patches the distutils.core.Distribution class
# So we need to import it before importing the Distribution class
@ -44,7 +44,10 @@ try:
except ImportError:
from distutils.core import Distribution
executables = None
from distutils.command.register import register
from distutils.command.install_lib import install_lib
from distutils import util
from distutils.file_util import write_file
AppName = "Patool"
AppVersion = "1.1"
@ -74,6 +77,36 @@ MSVCP90Version = '9.0.21022.8'
MSVCP90Token = '1fc8b3b9a1e18e3b'
def normpath (path):
"""Norm a path name to platform specific notation."""
return os.path.normpath(path)
def cnormpath (path):
"""Norm a path name to platform specific notation and make it absolute."""
path = normpath(path)
if os.name == 'nt':
# replace slashes with backslashes
path = path.replace("/", "\\")
if not os.path.isabs(path):
path = normpath(os.path.join(sys.prefix, path))
return path
release_ro = re.compile(r"\(released (.+)\)")
def get_release_date ():
"""Parse and return relase date as string from doc/changelog.txt."""
fname = os.path.join("doc", "changelog.txt")
release_date = "unknown"
with open(fname) as fd:
# the release date is on the first line
line = fd.readline()
mo = release_ro.search(line)
if mo:
release_date = mo.groups(1)
return release_date
data_files = []
if os.name == 'nt':
data_files.append(('share', ['doc/patool.txt']))
@ -121,6 +154,63 @@ if 'py2exe' in sys.argv[1:]:
add_msvc_files(data_files)
class MyInstallLib (install_lib, object):
"""Custom library installation."""
def install (self):
"""Install the generated config file."""
outs = super(MyInstallLib, self).install()
infile = self.create_conf_file()
outfile = os.path.join(self.install_dir, os.path.basename(infile))
self.copy_file(infile, outfile)
outs.append(outfile)
return outs
def create_conf_file (self):
"""Create configuration file."""
cmd_obj = self.distribution.get_command_obj("install")
cmd_obj.ensure_finalized()
# we have to write a configuration file because we need the
# <install_data> directory (and other stuff like author, url, ...)
# all paths are made absolute by cnormpath()
data = []
for d in ['purelib', 'platlib', 'lib', 'headers', 'scripts', 'data']:
attr = 'install_%s' % d
if cmd_obj.root:
# cut off root path prefix
cutoff = len(cmd_obj.root)
# don't strip the path separator
if cmd_obj.root.endswith(os.sep):
cutoff -= 1
val = getattr(cmd_obj, attr)[cutoff:]
else:
val = getattr(cmd_obj, attr)
if attr == 'install_data':
cdir = os.path.join(val, "share", "dosage")
data.append('config_dir = %r' % cnormpath(cdir))
elif attr == 'install_lib':
if cmd_obj.root:
_drive, tail = os.path.splitdrive(val)
if tail.startswith(os.sep):
tail = tail[1:]
self.install_lib = os.path.join(cmd_obj.root, tail)
else:
self.install_lib = val
data.append("%s = %r" % (attr, cnormpath(val)))
self.distribution.create_conf_file(data, directory=self.install_lib)
return self.get_conf_output()
def get_conf_output (self):
"""Get filename for distribution configuration file."""
return self.distribution.get_conf_filename(self.install_lib)
def get_outputs (self):
"""Add the generated config file to the list of outputs."""
outs = super(MyInstallLib, self).get_outputs()
outs.append(self.get_conf_output())
return outs
class MyDistribution (Distribution, object):
"""Custom distribution class generating config file."""
@ -129,6 +219,43 @@ class MyDistribution (Distribution, object):
super(MyDistribution, self).__init__(attrs)
self.console = ['patool']
def run_commands (self):
"""Generate config file and run commands."""
cwd = os.getcwd()
data = []
data.append('config_dir = %r' % os.path.join(cwd, "config"))
data.append("install_data = %r" % cwd)
data.append("install_scripts = %r" % cwd)
self.create_conf_file(data)
super(MyDistribution, self).run_commands()
def get_conf_filename (self, directory):
"""Get name for config file."""
return os.path.join(directory, "_%s_configdata.py" % self.get_name())
def create_conf_file (self, data, directory=None):
"""Create local config file from given data (list of lines) in
the directory (or current directory if not given)."""
data.insert(0, "# this file is automatically created by setup.py")
data.insert(0, "# -*- coding: iso-8859-1 -*-")
if directory is None:
directory = os.getcwd()
filename = self.get_conf_filename(directory)
# add metadata
metanames = ("name", "version", "author", "author_email",
"maintainer", "maintainer_email", "url",
"license", "description", "long_description",
"keywords", "platforms", "fullname", "contact",
"contact_email")
for name in metanames:
method = "get_" + name
val = getattr(self.metadata, method)()
data.append("%s = %r" % (name, val))
data.append('release_date = "%s"' % get_release_date())
# write the config file
util.execute(write_file, (filename, data),
"creating %s" % filename, self.verbose >= 1, self.dry_run)
class InnoScript:
"""Class to generate INNO script."""
@ -343,6 +470,7 @@ installed.
],
distclass = MyDistribution,
cmdclass = {
'install_lib': MyInstallLib,
'py2exe': MyPy2exe,
'register': MyRegister,
},