244 lines
9.6 KiB
Python
244 lines
9.6 KiB
Python
# libgo - script to build library.gnome.org
|
|
# Copyright (C) 2007-2009 Frederic Peters
|
|
#
|
|
# This program is free software; you can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License as published by
|
|
# the Free Software Foundation; either version 2 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with this program; if not, write to the Free Software
|
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
# 02110-1301 USA
|
|
|
|
import logging
|
|
import os
|
|
import re
|
|
import stat
|
|
import tarfile
|
|
|
|
from utils import version_cmp, is_version_number
|
|
|
|
class DocModule(object):
|
|
'''Base class for documentation shipped in tarballs'''
|
|
makefile_am = None
|
|
|
|
filename = None
|
|
dirname = None
|
|
modulename = None
|
|
|
|
related_xsl_files = None
|
|
mtime_xslt_files = 0
|
|
|
|
channel = None
|
|
nightly = False
|
|
extra_devel_releases = None
|
|
|
|
def create_from_tar(cls, tar, tarinfo, makefile_am, nightly = False):
|
|
self = cls()
|
|
if tarinfo.isdir():
|
|
self.dirname = tarinfo.name
|
|
else:
|
|
self.dirname = os.path.dirname(tarinfo.name)
|
|
if makefile_am:
|
|
self.makefile_am = makefile_am
|
|
self.modulename = re.findall(r'(?:DOC_ID|DOC_MODULE|HELP_ID)\s?=\s?(.*)',
|
|
makefile_am)[0].strip()
|
|
|
|
if '@' in self.modulename:
|
|
logging.warning('variadic module name: %s' % self.modulename)
|
|
# don't go interpreting autotools variables, as in this path
|
|
# lays madness, instead simply cut out the variable, such as
|
|
# gnome-scan-@API_VERSION@ becomes gnome-scan.
|
|
self.modulename = self.modulename.split('@')[0].strip('-')
|
|
# remove the version part, so libsoup-2.4 is handled just like
|
|
# another version of libsoup
|
|
self.modulename = re.sub('-\d+\.\d+$', '', self.modulename)
|
|
self.version = os.path.splitext(tar.name)[0].split('-')[-1]
|
|
if self.version.endswith('.tar'):
|
|
self.version = self.version[:-4]
|
|
|
|
if nightly or self.version == 'nightly':
|
|
self.nightly = True
|
|
self.version = 'nightly'
|
|
self.one_dot_version = 'nightly'
|
|
else:
|
|
self.one_dot_version = re.match(r'\d+\.\d+', self.version).group()
|
|
|
|
if self.related_xsl_files:
|
|
self.mtime_xslt_files = max([os.stat(
|
|
os.path.join(data_dir, 'xslt', x))[stat.ST_MTIME] \
|
|
for x in self.related_xsl_files])
|
|
return self
|
|
create_from_tar = classmethod(create_from_tar)
|
|
|
|
def extract(self, force=False):
|
|
'''Extract a given module out of a tarball; extraction will not happen
|
|
if the output directory already exists, unless @force is given.'''
|
|
|
|
ext_dirname = os.path.join(app.config.private_dir, 'extracts')
|
|
if not os.path.exists(ext_dirname):
|
|
os.makedirs(ext_dirname)
|
|
|
|
base_tarball_name = os.path.basename(self.filename).rsplit('-', 1)[0]
|
|
|
|
dirname = self.dirname
|
|
if dirname.endswith('/'):
|
|
dirname = dirname[:-1]
|
|
|
|
if not os.path.exists(os.path.join(ext_dirname, self.dirname)) or force:
|
|
logging.debug('extracting %s' % self.dirname)
|
|
tar = tarfile.open(self.filename, 'r')
|
|
for tarinfo in tar.getmembers():
|
|
if not os.path.split(tarinfo.name)[0].startswith(dirname):
|
|
continue
|
|
dest = os.path.join(ext_dirname, tarinfo.name)
|
|
if tarinfo.isdir() and not os.path.exists(dest):
|
|
os.makedirs(dest)
|
|
elif tarinfo.isreg():
|
|
if not os.path.exists(os.path.dirname(dest)):
|
|
os.makedirs(os.path.dirname(dest))
|
|
open(dest, 'w').write(tar.extractfile(tarinfo).read())
|
|
tar.close()
|
|
return True
|
|
return False
|
|
|
|
def get_libgo_document(self, doc_linguas):
|
|
try:
|
|
doc = [x for x in app.documents if \
|
|
x.module == self.modulename and x.channel == self.channel][0]
|
|
except IndexError:
|
|
doc = app.Document()
|
|
doc.filename = self.dirname
|
|
doc.module = self.modulename
|
|
doc.channel = self.channel
|
|
doc.languages = doc_linguas
|
|
doc.path = self.path
|
|
doc._last_version = self.version
|
|
doc.versions = [self.one_dot_version]
|
|
app.documents.append(doc)
|
|
else:
|
|
if doc._last_version == self.version:
|
|
# file was already processed in a previous moduleset
|
|
return None
|
|
|
|
if not self.nightly:
|
|
# a more recent version may already have been installed; probably
|
|
# because the same module is being mentioned as an extra tarball
|
|
# with an inferior version number; don't update path in this
|
|
# situation. (see bug #530517 for the mention of this problem)
|
|
if version_cmp(doc._last_version, self.version) <= 0:
|
|
doc._last_version = self.version
|
|
if int(self.one_dot_version.split('.')[1]) % 2 == 0:
|
|
# update path to point to the latest version (but no
|
|
# development versions)
|
|
doc.path = self.path
|
|
|
|
if not self.one_dot_version in doc.versions:
|
|
doc.versions.append(self.one_dot_version)
|
|
for lang in doc_linguas:
|
|
if not lang in doc.languages:
|
|
doc.languages.append(lang)
|
|
|
|
doc.version_mapping[self.one_dot_version] = self.version
|
|
|
|
# only keep authorised languages
|
|
if app.config.languages:
|
|
for lang in doc.languages[:]:
|
|
if lang not in app.config.languages:
|
|
doc.languages.remove(lang)
|
|
|
|
return doc
|
|
|
|
def is_development_release(self):
|
|
development_release = (int(self.one_dot_version.split('.')[1]) % 2 == 1) or (
|
|
int(self.one_dot_version.split('.')[0]) == 0)
|
|
if not development_release:
|
|
development_release = app.overlay.is_development_release(
|
|
self.modulename, self.one_dot_version)
|
|
return development_release
|
|
|
|
def install_version_symlinks(self, doc):
|
|
'''Create stable and devel symlinks'''
|
|
|
|
if self.nightly:
|
|
return
|
|
|
|
if self.channel not in ('users', 'devel', 'admin'):
|
|
return
|
|
|
|
if not self.one_dot_version in doc.versions:
|
|
# this version doesn't appear in available versions, probably it
|
|
# had been depreciated
|
|
return
|
|
|
|
web_output_dir = app.get_module_web_output_dir(self, versioned=False)
|
|
development_release = self.is_development_release()
|
|
|
|
if development_release:
|
|
keyword = 'unstable'
|
|
else:
|
|
keyword = 'stable'
|
|
|
|
path = os.path.join(web_output_dir, keyword)
|
|
installed = False
|
|
if os.path.islink(path):
|
|
currently_marked = os.readlink(path)
|
|
if currently_marked == 'stable':
|
|
currently_marked = os.readlink(os.path.join(web_output_dir, 'stable'))
|
|
if version_cmp(self.version, currently_marked) >= 0:
|
|
# install new symlink
|
|
os.unlink(path)
|
|
os.symlink(self.one_dot_version, path)
|
|
installed = True
|
|
else:
|
|
os.symlink(self.one_dot_version, path)
|
|
installed = True
|
|
|
|
if installed:
|
|
base_path = app.config.doc_path_template % {
|
|
'channel': self.channel,
|
|
'module': self.modulename }
|
|
if not development_release:
|
|
if doc.path == base_path + '%s/' % self.one_dot_version:
|
|
# set default path to use the keyword
|
|
doc.path = base_path + 'stable/'
|
|
|
|
# if there is no unstable link, create it even for a stable release
|
|
# (or if stable is newer)
|
|
path = os.path.join(web_output_dir, 'unstable')
|
|
if os.path.islink(path):
|
|
currently_unstable = os.readlink(path)
|
|
if currently_unstable == 'stable' or \
|
|
version_cmp(self.version, currently_unstable) >= 0:
|
|
os.unlink(path)
|
|
os.symlink('stable', path)
|
|
else:
|
|
os.symlink('stable', path)
|
|
elif not os.path.exists(os.path.join(web_output_dir, 'stable')):
|
|
# update default path to have codename if there is no stable
|
|
# release
|
|
doc.path = base_path + 'unstable/'
|
|
|
|
for k in doc.version_keywords.keys():
|
|
if doc.version_keywords.get(k) == keyword:
|
|
del doc.version_keywords[k]
|
|
doc.version_keywords[self.one_dot_version] = keyword
|
|
|
|
def create_tarball_symlink(self, doc):
|
|
tarball_dest = '../%s-html-%s.tar.gz' % (self.modulename, self.version)
|
|
in_version_path = os.path.join(
|
|
app.get_module_web_output_dir(self),
|
|
'%s-html.tar.gz' % self.modulename)
|
|
if not self.one_dot_version in in_version_path:
|
|
return
|
|
if os.path.islink(in_version_path):
|
|
os.unlink(in_version_path)
|
|
os.symlink(tarball_dest, in_version_path)
|
|
|