import re
import stat
import sys
+import tempfile
import traceback
+import subprocess as sp
from pygnulib.error import CommandLineError
from pygnulib.error import UnknownModuleError
from pygnulib.config import Cache as CacheConfig
from pygnulib.generator import CommandLine as CommandLineGenerator
+from pygnulib.generator import GnulibCache as GnulibCacheGenerator
from pygnulib.generator import LibMakefile as LibMakefileGenerator
+from pygnulib.generator import POMakevars as POMakevarsGenerator
from pygnulib.module import filelist
from pygnulib.module import dummy_required
from pygnulib.parser import CommandLine as CommandLineParser
-from pygnulib.vfs import backup
-from pygnulib.vfs import compare
-from pygnulib.vfs import copy
-from pygnulib.vfs import exists
-from pygnulib.vfs import hardlink
-from pygnulib.vfs import lookup
-from pygnulib.vfs import move
-from pygnulib.vfs import symlink
-from pygnulib.vfs import unlink
+from pygnulib.vfs import backup as vfs_backup
+from pygnulib.vfs import compare as vfs_compare
+from pygnulib.vfs import copy as vfs_copy
+from pygnulib.vfs import exists as vfs_exists
+from pygnulib.vfs import hardlink as vfs_hardlink
+from pygnulib.vfs import lookup as vfs_lookup
+from pygnulib.vfs import move as vfs_move
+from pygnulib.vfs import iostream as vfs_iostream
+from pygnulib.vfs import symlink as vfs_symlink
+from pygnulib.vfs import unlink as vfs_unlink
from pygnulib.vfs import Base as BaseVFS
from pygnulib.vfs import GnulibGit as GnulibGitVFS
"unlimited",
"unmodifiable license text",
}
+TRANSFER_MODES = {
+ None: vfs_copy,
+ "hardlink": vfs_hardlink,
+ "symlink": vfs_symlink,
+}
SUBSTITUTION_RULES = {
"build-aux": "auxdir",
"doc": "doc_base",
"po": "po_base",
"top": "",
}
+TP_URL = "http://translationproject.org/latest/"
+TP_RSYNC_URI = "translationproject.org::tp/latest/"
def list_hook(gnulib, *args, **kwargs):
(_, _) = (args, kwargs)
for module in sorted(gnulib.modules(full=False)):
- print(module.name)
+ print(module.name, file=sys.stdout)
return os.EX_OK
old_files |= set(["m4/gnulib-tool.m4"])
for (tbl_key, cfg_key) in SUBSTITUTION_RULES.items():
table[tbl_key] = cache[cfg_key] if cfg_key else ""
- with BaseVFS(config.root, **table) as vfs:
- old_files = frozenset({vfs[file] for file in old_files})
new_files = frozenset(files | set(["m4/gnulib-tool.m4"]))
dry_run = options["dry_run"]
def transfer_file(local, src_vfs, src_name, dst_vfs, dst_name):
args = (src_vfs, src_name, dst_vfs, dst_name)
if src_vfs is None:
- return copy(*args)
- table = {None: copy, "hardlink": hardlink, "symlink": symlink}
- action = table[local_copymode if local else gnulib_copymode]
+ return vfs_copy(*args)
+ action = TRANSFER_MODES[local_copymode if local else gnulib_copymode]
try:
return action(*args)
except OSError as error:
if error.errno == errno.EXDEV:
- return copy(*args)
+ return vfs_copy(*args)
raise error
def remove_file(project, file):
action = ("Removing", "Remove")[dry_run]
fmt = (action + " file {file} (backup in {file}~)")
if not dry_run:
- unlink(project, file, backup=True)
- print(fmt.format(file=file))
+ vfs_unlink(project, file, backup=True)
+ print(fmt.format(file=file), file=sys.stdout)
def update_file(local, src_vfs, src_name, dst_vfs, dst_name, present):
- if not compare(src_vfs, src_name, dst_vfs, dst_name):
+ if not vfs_compare(src_vfs, src_name, dst_vfs, dst_name):
action = (("Replacing", "Replace"), ("Updating", "Update"))[present][dry_run]
message = ("(non-gnulib code backed up in {file}~) !!", "(backup in {file}~)")[present]
fmt = (action + " file {file} " + message)
if not dry_run:
- backup(dst_vfs, dst_name)
+ vfs_backup(dst_vfs, dst_name)
transfer_file(local, src_vfs, src_name, dst_vfs, dst_name)
- print(fmt.format(file=dst_name))
+ print(fmt.format(file=dst_name), file=sys.stdout)
def add_file(local, src_vfs, src_name, dst_vfs, dst_name, present):
action = ("Copying", "Copy")[dry_run]
fmt = (action + " file {file}")
if not dry_run:
transfer_file(local, src_vfs, src_name, dst_vfs, dst_name)
- print(fmt.format(file=dst_name))
+ print(fmt.format(file=dst_name), file=sys.stdout)
# First the files that are in old_files, but not in new_files.
# Then the files that are in new_files, but not in old_files.
remove_file(project, file)
for (present, files) in ((False, added_files), (True, kept_files)):
for dst in sorted(files):
- match = [override for override in overrides if dst in override]
- override = match[0] if len(match) else gnulib
- (vfs, src) = lookup(dst, gnulib, override, patch="patch")
- action = update_file if exists(project, dst) else add_file
+ match = tuple(override for override in overrides if dst in override)
+ override = match[0] if match else gnulib
+ (vfs, src) = vfs_lookup(dst, gnulib, override, patch="patch")
+ action = update_file if vfs_exists(project, dst) else add_file
+ action(bool(match), vfs, src, project, dst, present)
+
+ mkedits = []
+ if config.makefile_name == "Makefile.am":
+ dirname = os.path.dirname(config.source_base)
+ basename = os.path.basename(config.source_base)
+ dirname = "" if dirname == "." else (dirname + os.path.sep)
+ mkedits.append((dirname, "SUBDIRS", basename))
+ if "po_base" in explicit:
+ dirname = os.path.dirname(config.po_base)
+ basename = os.path.basename(config.po_base)
+ dirname = "" if dirname == "." else dirname
+ mkedits.append((dirname, "SUBDIRS", basename))
+ if config.tests and config.makefile_name == "Makefile.am":
+ dirname = os.path.dirname(config.tests_base)
+ basename = os.path.basename(config.tests_base)
+ dirname = "" if dirname == "." else (dirname + os.path.sep)
+ mkedits.append((dirname, "SUBDIRS", basename))
+ mkedits.append(("", "ACLOCAL_AMFLAGS", "-I {}".format(config.m4_base)))
+
+ # Find the first parent directory of m4_base that contains or will contain a Makefile.am.
+ (dir1, dir2) = (config.m4_base, "")
+ source_base_makefile = os.path.join(config.source_base, config.makefile_name)
+ tests_base_makefile = os.path.join(config.tests_base, config.makefile_name)
+ while dir1 != ".":
+ path = os.path.join(dir1, "Makefile.am")
+ if vfs_exists(project, os.path.join(config.root, dir1, "Makefile.am")) \
+ or (config.tests and path in (source_base_makefile, tests_base_makefile)):
+ break
+ dir2 = os.path.join(os.path.basename(dir1), dir2)
+ dir1 = os.path.dirname(dir1)
+ mkedits.append((dir1, "EXTRA_DIST", os.path.join(dir2, "gnulib-cache.m4")))
+
+ # Generate the contents of library makefile.
+ path = os.path.join(config.source_base, config.makefile_name)
+ with tempfile.NamedTemporaryFile("w", encoding="UTF-8", delete=False) as tmp:
+ for line in LibMakefileGenerator(config, explicit, path, main, mkedits, False):
+ tmp.write(line + "\n")
+ (src, dst) = (tmp.name, path)
+ present = vfs_exists(project, dst)
+ if present:
+ added_files.add(dst)
+ action = update_file if present else add_file
+ action(False, None, src, project, dst, present)
+ os.unlink(tmp.name)
+
+ # Generate po makefile and directories.
+ url = (TP_RSYNC_URI + "gnulib/")
+ if "po_base" in explicit:
+ for file in ("Makefile.in.in", "remove-potcdate.sin"):
+ path = os.path.join("build-aux", "po", file)
+ match = tuple(override for override in overrides if file in override)
+ override = match[0] if match else gnulib
+ (vfs, src) = vfs_lookup(path, gnulib, override, patch="patch")
+ dst = os.path.join("po", file)
+ present = vfs_exists(project, dst)
+ if present:
+ added_files.add(dst)
+ action = update_file if present else add_file
action(bool(match), vfs, src, project, dst, present)
+ # Create po makefile parameterization, part 1.
+ with tempfile.NamedTemporaryFile("w", encoding="UTF-8", delete=False) as tmp:
+ for line in POMakevarsGenerator(config):
+ tmp.write(line + "\n")
+ (src, dst) = (tmp.name, "po/Makevars")
+ present = vfs_exists(project, dst)
+ if present:
+ added_files.add(dst)
+ action = update_file if present else add_file
+ action(False, None, src, project, dst, present)
+ os.unlink(tmp.name)
+ # Create po makefile parameterization, part 2.
+ with tempfile.NamedTemporaryFile("w", encoding="UTF-8", delete=False) as tmp:
+ for line in POMakevarsGenerator(config):
+ tmp.write(line + "\n")
+ (src, dst) = (tmp.name, "po/POTFILES.in")
+ present = vfs_exists(project, dst)
+ if present:
+ added_files.add(dst)
+ action = update_file if present else add_file
+ action(False, None, src, project, dst, present)
+ os.unlink(tmp.name)
+ # Fetch PO files.
+ po_root = os.path.join(project.absolute, project["po"])
+ fmt = ("{} gnulib PO files from " + TP_URL)
+ print(fmt.format("Fetching", "Fetch")[dry_run], file=sys.stdout)
+ if not dry_run:
+ # Prefer rsync over wget if it is available, since it consumes
+ # less network bandwidth, due to compression.
+ url = (TP_RSYNC_URI + "gnulib/")
+ cmdargs = ("rsync", "--delete", "--exclude", "*.s1", "-Lrtz", url, ".")
+ with sp.Popen(cmdargs, cwd=po_root, stdout=sp.PIPE, stderr=sp.PIPE) as process:
+ (stdout, stderr) = process.communicate()
+ stdout = stdout.decode("UTF-8")
+ stderr = stderr.decode("UTF-8")
+ returncode = process.returncode
+ if process.returncode == 0:
+ raise sp.CalledProcessError(returncode, cmdargs, stdout, stderr)
+ print(stdout, file=sys.stdout)
+ print(stderr, file=sys.stderr)
+ # Create po/LINGUAS.
+ languages = set()
+ for root, _, files in os.walk(po_root):
+ languages.update(file[:-3] for file in files if file.endswith(".po"))
+ with tempfile.NamedTemporaryFile("w", encoding="UTF-8", delete=False) as tmp:
+ tmp.write("# Set of available languages.\n")
+ for line in sorted(languages):
+ tmp.write(line + "\n")
+ (src, dst) = (tmp.name, "po/LINGUAS")
+ present = vfs_exists(project, dst)
+ if present:
+ added_files.add(dst)
+ action = update_file if present else add_file
+ action(False, None, src, project, dst, present)
+ os.unlink(tmp.name)
+
+ # Create m4/gnulib-cache.m4.
+ with tempfile.NamedTemporaryFile("w", encoding="UTF-8", delete=False) as tmp:
+ for line in GnulibCacheGenerator(config):
+ tmp.write(line + "\n")
+ (src, dst) = (tmp.name, "m4/gnulib-cache.m4")
+ present = vfs_exists(project, dst)
+ if present:
+ added_files.add(dst)
+ action = update_file if present else add_file
+ action(False, None, src, project, dst, present)
+ os.unlink(tmp.name)
- actioncmd = " ".join(CommandLineGenerator(config, explicit))
- libMakefile = LibMakefileGenerator(config, explicit, main, False, actioncmd=actioncmd)
return os.EX_OK
return _re.compile(regex, _re.S | _re.M)
-_ITERABLES = (list, tuple, set, frozenset)
+_ITERABLES = frozenset((list, tuple, set, frozenset, type({}.keys()), type({}.values())))
"doc_base" : "doc",
"tests_base" : "tests",
"auxdir" : "",
- "lib" : "libgnu",
+ "libname" : "libgnu",
"makefile_name" : "Makefile.am",
"macro_prefix" : "gl",
"po_domain" : "",
@property
- def lib(self):
+ def libname(self):
"""library name; defaults to 'libgnu'"""
- return self.__table["lib"]
+ return self.__table["libname"]
- @lib.setter
- def lib(self, value):
- _type_assert("lib", value, str)
- self.__table["lib"] = value if value else "libgnu"
+ @libname.setter
+ def libname(self, value):
+ _type_assert("libname", value, str)
+ self.__table["libname"] = value if value else "libgnu"
@property
"""include guard prefix"""
prefix = self.__table["macro_prefix"].upper()
default = Base._TABLE["macro_prefix"].upper()
- return "GL_{0}".format(prefix) if prefix == default else "GL"
+ return "GL" if prefix == default else "GL_{0}".format(prefix)
@property
"macro_prefix" : (str, _compile(r"gl_MACRO_PREFIX\(\[(.*?)\]\)")),
"po_domain" : (str, _compile(r"gl_PO_DOMAIN\(\[(.*?)\]\)")),
"witness_c_macro" : (str, _compile(r"gl_WITNESS_C_MACRO\(\[(.*?)\]\)")),
- "lib" : (str, _compile(r"gl_LIB\(\[(.*?)\]\)")),
+ "libname" : (str, _compile(r"gl_LIB\(\[(.*?)\]\)")),
"modules" : (list, _compile(r"gl_MODULES\(\[(.*?)\]\)")),
"avoids" : (list, _compile(r"gl_AVOID\(\[(.*?)\]\)")),
"licenses" : (str, _compile(r"gl_LGPL\(\[(.*?)\]\)")),
-_ITERABLES = (list, tuple, set, frozenset, type({}.keys()), type({}.values()))
+
+_LGPL = {
+ _LGPLv2_LICENSE: "2",
+ _LGPLv3_LICENSE: "3",
+ _LGPL_LICENSE: "yes",
+ (_GPLv2_LICENSE | _LGPLv3_LICENSE): "3orGPLv2",
+}
+_ITERABLES = frozenset((list, tuple, set, frozenset, type({}.keys()), type({}.values())))
-class POMakefile(Generator):
+class POMakevars(Generator):
"""PO Makefile parameterization"""
_TEMPLATE = (
"# These options get passed to xgettext.",
yield "# These two variables depend on the location of this directory."
yield "subdir = {}".format(self.po_domain)
yield "top_subdir = {}".format("/".join(".." for _ in self.po_base.split(_os.path.sep)))
- for line in POMakefile._TEMPLATE:
+ for line in POMakevars._TEMPLATE:
yield line
+class CommandLine(Generator):
+ """gnulib command-line invocation generator"""
+ _TESTS = {
+ "tests": "tests",
+ "obsolete": "obsolete",
+ "cxx_tests": "c++-tests",
+ "longrunning_tests": "longrunning-tests",
+ "privileged_tests": "privileged-tests",
+ "unportable_tests": "unportable-tests",
+ }
+
+ def __init__(self, config, explicit):
+ _type_assert("config", config, _BaseConfig)
+ _type_assert("explicit", explicit, _ITERABLES)
+ self.__config = config
+ self.__explicit = explicit
+
+
+ def __iter__(self):
+ config = self.__config
+ explicit = self.__explicit
+ yield "gnulib-tool --import"
+ for path in config.overrides:
+ yield "--local-dir={}".format(path)
+ yield "--lib={}".format(config.libname)
+ yield "--source-base={}".format(config.source_base)
+ yield "--m4-base={}".format(config.m4_base)
+ if "po_base" in explicit:
+ yield "--po-base={}".format(config.po_base)
+ yield "--doc-base={}".format(config.doc_base)
+ yield "--tests-base={}".format(config.tests_base)
+ yield "--aux-dir={}".format(config.auxdir)
+ for (key, value) in CommandLine._TESTS.items():
+ if config[key]:
+ yield "--with-{}".format(value)
+ if config.all_tests:
+ yield "--with-all-tests"
+ for module in config.avoids:
+ yield "--avoid={}".format(module)
+ if config.licenses in _LGPL:
+ lgpl = _LGPL[config.licenses]
+ yield "--lgpl={}".format(lgpl) if lgpl != "yes" else "--lgpl"
+ if config.gnumake:
+ yield "--gnu-make"
+ if "makefile_name" in explicit:
+ yield "--makefile-name={}".format(config.makefile_name)
+ yield "--{}conditional-dependencies".format("" if config.conddeps else "no-")
+ yield "--{}libtool".format("" if config.libtool else "no-")
+ yield "--macro-prefix={}".format(config.macro_prefix)
+ if "po_domain" in explicit:
+ yield "--po-domain={}".format(config.po_domain)
+ if "witness_c_macro" in explicit:
+ yield "--witness-c-macro={}".format(config.witness_c_macro)
+ if "vc_files" in explicit:
+ yield "--{}vc-files".format("" if config.vc_files else "no-")
+ for module in sorted(config.modules):
+ yield "{}".format(module)
+
+
+
class LibMakefile(Generator):
_LDFLAGS = _re.compile(r"^lib_LDFLAGS\s*\+\=.*?$", _re.S)
_LIBNAME = _re.compile(r"lib_([A-Z][A-Z]*)", _re.S)
_GNUMAKE = _re.compile(r"^if (.*?)$", _re.S)
- def __init__(self, config, explicit, modules, for_test,
- autoconf="autoconf", configure_ac="configure.ac", actioncmd=""):
+ def __init__(self, config, explicit, path, modules, mkedits, for_test):
_type_assert("config", config, _BaseConfig)
_type_assert("explicit", explicit, _ITERABLES)
+ _type_assert("path", path, str)
_type_assert("modules", modules, _ITERABLES)
+ _type_assert("mkedits", mkedits, _ITERABLES)
_type_assert("for_test", for_test, bool)
- _type_assert("actioncmd", actioncmd, str)
- _type_assert("autoconf", autoconf, str)
- _type_assert("configure_ac", configure_ac, str)
self.__config = config
self.__explicit = explicit
+ self.__path = path
self.__modules = modules
+ self.__mkedits = mkedits
self.__for_test = for_test
- self.__actioncmd = actioncmd
- self.__autoconf = autoconf
- self.__configure_ac = configure_ac
def __iter__(self):
config = self.__config
explicit = self.__explicit
for_test = self.__for_test
- actioncmd = self.__actioncmd
modules = self.__modules
gnumake = config.gnumake
libtool = config.libtool
kwargs = {
- "libname": config.lib,
+ "libname": config.libname,
"macro_prefix": config.macro_prefix,
"libext": "la" if libtool else "a",
"perhaps_LT": "LT" if libtool else "",
# that is to be preprocessed by config.status is 3070. config.status uses
# awk, and the HP-UX 11.00 awk fails if a line has length >= 3071;
# similarly, the IRIX 6.5 awk fails if a line has length >= 3072.
+ actioncmd = " ".join(CommandLine(config, explicit))
if len(actioncmd) <= 3000:
yield "# Reproduce by: {}".format(actioncmd)
yield ""
if transform_check_PROGRAMS:
conditional = conditional.replace("check_PROGRAMS", "noinst_PROGRAMS")
conditional = conditional.replace(r"${gl_include_guard_prefix}", config.include_guard_prefix)
- unconditional = module.unconditional_automake_snippet
+ unconditional = module.unconditional_automake_snippet(config.auxdir)
unconditional = LibMakefile._LIBNAME.sub("{libname}_{libext}_\\1".format(**kwargs), unconditional)
if (conditional + unconditional).strip():
lines.append("## begin gnulib module {}".format(module.name))
if gnumake:
yield "# Start of GNU Make output."
+ self.__autoconf = "autoconf"
+ self.__configure_ac = "configure.ac"
cmdargs = (self.__autoconf, "-t", "AC_SUBST:$1 = @$1@", self.__configure_ac)
- process = _sp.Popen(cmdargs, stdout=_sp.PIPE, stderr=_sp.PIPE)
- (stdout, stderr) = process.communicate()
- stdout = stdout.decode("UTF-8")
- stderr = stderr.decode("UTF-8")
- if process.returncode == 0:
- for line in sorted(stdout.splitlines()):
- yield line
- else:
- yield "== gnulib-tool GNU Make output failed as follows =="
- for line in stderr.splitlines():
- yield "# stderr: {}".format(line)
+ with _sp.Popen(cmdargs, stdout=_sp.PIPE, stderr=_sp.PIPE) as process:
+ (stdout, stderr) = process.communicate()
+ stdout = stdout.decode("UTF-8")
+ stderr = stderr.decode("UTF-8")
+ if process.returncode == 0:
+ for line in sorted(stdout.splitlines()):
+ yield line
+ else:
+ yield "== gnulib-tool GNU Make output failed as follows =="
+ for line in stderr.splitlines():
+ yield "# stderr: {}".format(line)
yield "# End of GNU Make output."
else:
yield "# No GNU Make output."
+ for (directory, key, value) in self.__mkedits:
+ if key and _os.path.join(directory, "Makefile.am") == self.__path:
+ yield f"{key} += {value}"
+
cppflags = "".join((
" -D{}=1".format(config.witness_c_macro) if "witness_c_macro" in explicit else "",
" -DGNULIB_STRICT_CHECKING=1" if for_test else "",
-class CommandLine(Generator):
- """gnulib command-line invocation generator"""
- _TESTS = {
- "tests": "tests",
- "obsolete": "obsolete",
- "cxx_tests": "c++-tests",
- "longrunning_tests": "longrunning-tests",
- "privileged_tests": "privileged-tests",
- "unportable_tests": "unportable-tests",
- }
- _LGPL = {
- _LGPLv2_LICENSE: "2",
- _LGPLv3_LICENSE: "3",
- _LGPL_LICENSE: "yes",
- (_GPLv2_LICENSE | _LGPLv3_LICENSE): "3orGPLv2",
- }
-
- def __init__(self, config, explicit):
+class GnulibCache(Generator):
+ def __init__(self, config):
_type_assert("config", config, _BaseConfig)
- _type_assert("explicit", explicit, _ITERABLES)
self.__config = config
- self.__explicit = explicit
def __iter__(self):
+ date = _datetime.now()
config = self.__config
- explicit = self.__explicit
- yield "gnulib-tool --import"
- for path in config.overrides:
- yield "--local-dir={}".format(path)
- yield "--lib={}".format(config.lib)
- yield "--source-base={}".format(config.source_base)
- yield "--m4-base={}".format(config.m4_base)
- if "po_base" in explicit:
- yield "--po-base={}".format(config.po_base)
- yield "--doc-base={}".format(config.doc_base)
- yield "--tests-base={}".format(config.tests_base)
- yield "--aux-dir={}".format(config.auxdir)
- for (key, value) in CommandLine._TESTS.items():
- if config[key]:
- yield "--with-{}".format(value)
- if config.all_tests:
- yield "--with-all-tests"
- for module in config.avoids:
- yield "--avoid={}".format(module)
- if config.licenses in CommandLine._LGPL:
- lgpl = CommandLine._LGPL[config.licenses]
- yield "--lgpl={}".format(lgpl) if lgpl == "yes" else " --lgpl"
- if config.gnumake:
- yield "--gnu-make"
- if "makefile_name" in explicit:
- yield "--makefile-name={}".format(config.makefile_name)
- yield "--{}conditional-dependencies".format("" if config.conddeps else "no-")
- yield "--{}libtool".format("" if config.libtool else "no-")
- yield "--macro-prefix={}".format(config.macro_prefix)
- if "po_domain" in explicit:
- yield "--po-domain={}".format(config.po_domain)
- if "witness_c_macro" in explicit:
- yield "--witness-c-macro={}".format(config.witness_c_macro)
- if "vc_files" in explicit:
- yield "--{}vc-files".format("" if config.vc_files else "no-")
+ yield "## DO NOT EDIT! GENERATED AUTOMATICALLY!"
+ yield "## Process this file with automake to produce Makefile.in."
+ yield "# Copyright (C) 2002-{} Free Software Foundation, Inc.".format(date.year)
+ for line in super().__iter__():
+ yield line
+ yield "#"
+ yield "# This file represents the specification of how gnulib-tool is used."
+ yield "# It acts as a cache: It is written and read by gnulib-tool."
+ yield "# In projects that use version control, this file is meant to be put under"
+ yield "# version control, like the configure.ac and various Makefile.am files."
+ yield ""
+ yield ""
+ yield "# Specification in the form of a command-line invocation:"
+ yield "gl_LOCAL_DIR([$relative_local_gnulib_path])"
+ yield "gl_MODULES(["
for module in sorted(config.modules):
- yield "{}".format(module)
+ yield " {}".format(module)
+ yield "])"
+ if config.obsolete:
+ yield "gl_WITH_OBSOLETE"
+ if config.cxx_tests:
+ yield "gl_WITH_CXX_TESTS"
+ if config.longrunning_tests:
+ yield "gl_WITH_LONGRUNNING_TESTS"
+ if config.privileged_tests:
+ yield "gl_WITH_PRIVILEGED_TESTS"
+ if config.unportable_tests:
+ yield "gl_WITH_UNPORTABLE_TESTS"
+ if config.all_tests:
+ yield "gl_WITH_ALL_TESTS"
+ yield "gl_AVOID([{}])".format(" ".join(sorted(config.avoids)))
+ yield "gl_SOURCE_BASE([{}])".format(config.source_base)
+ yield "gl_M4_BASE([{}])".format(config.m4_base)
+ yield "gl_PO_BASE([{}])".format(config.po_base)
+ yield "gl_DOC_BASE([{}])".format(config.doc_base)
+ yield "gl_TESTS_BASE([{}])".format(config.tests_base)
+ if config.tests:
+ yield "gl_WITH_TESTS"
+ yield "gl_LIB([{}])".format(config.libname)
+ if config.licenses in _LGPL:
+ lgpl = _LGPL[config.licenses]
+ yield "gl_LGPL([{}])".format(lgpl) if lgpl != "yes" else "gl_LGPL"
+ yield "gl_MAKEFILE_NAME([{}])".format(config.makefile_name)
+ if config.conddeps:
+ yield "gl_CONDITIONAL_DEPENDENCIES"
+ if config.libtool:
+ yield "gl_LIBTOOL"
+ yield "gl_MACRO_PREFIX([{}])".format(config.macro_prefix)
+ yield "gl_PO_DOMAIN([{}])".format(config.po_domain)
+ yield "gl_WITNESS_C_MACRO([{}])".format(config.witness_c_macro)
+ if config.vc_files:
+ yield "gl_VC_FILES([{}])".format(" ".join(sorted(config.vc_files)))
-_ITERABLES = (list, tuple, set, frozenset)
+_ITERABLES = frozenset((list, tuple, set, frozenset, type({}.keys()), type({}.values())))
self.__table["conditional_automake_snippet"] = value
- @property
- def unconditional_automake_snippet(self):
+ def unconditional_automake_snippet(self, auxdir):
"""Makefile.am snippet that must stay outside of Automake conditionals"""
if "unconditional_automake_snippet" in self.__table:
return self.__table["unconditional_automake_snippet"]
mentioned_files = tuple(_collections.OrderedDict.fromkeys(mentioned_files))
lib_files = tuple(file[len("lib/"):] for file in all_files if file.startswith("lib/"))
extra_files = tuple(file for file in lib_files if file not in mentioned_files)
- import sys
- if self.name == "getprogname":
- print(mentioned_files, file=sys.stderr)
if extra_files:
result += ("EXTRA_DIST += {}".format(" ".join(sorted(extra_files))) + "\n")
result += ("EXTRA_lib_SOURCES += {}".format(" ".join(sorted(extra_files))) + "\n")
# Synthesize an EXTRA_DIST augmentation also for the files in build-aux/.
+ prefix = _os.path.join("$(top_srcdir)", auxdir)
buildaux_files = (file for file in all_files if file.startswith("build-aux/"))
- buildaux_files = tuple("$(top_srcdir)/{auxdir}/" + file[len("build-aux/"):] for file in buildaux_files)
+ buildaux_files = tuple(_os.path.join(prefix, file[len("build-aux/"):]) for file in buildaux_files)
if buildaux_files:
result += ("EXTRA_DIST += {}".format(" ".join(sorted(buildaux_files))) + "\n")
self.__table["unconditional_automake_snippet"] = result
files.add("m4/gnulib-common.m4")
if ac_version == 2.59:
files.add("m4/onceonly.m4")
- return frozenset(files)
+ return files
def mkdir(root, name):
"""Create a leaf directory and all intermediate ones recursively."""
root = Base(".") if root is None else root
+ path = name if _os.path.isabs(name) else _os.path.join(root.absolute, root[name])
_os.makedirs(root[name], exist_ok=True)
"""Compare the given files; return True if files contain the same data."""
lhs_root = Base(".") if lhs_root is None else lhs_root
rhs_root = Base(".") if rhs_root is None else rhs_root
- lhs_path = _os.path.join(lhs_root.absolute, lhs_root[lhs_name])
- rhs_path = _os.path.join(rhs_root.absolute, rhs_root[rhs_name])
+ (lhs_path, rhs_path) = (lhs_name, rhs_name)
+ if not _os.path.isabs(lhs_name):
+ lhs_path = _os.path.join(lhs_root.absolute, lhs_root[lhs_name])
+ if not _os.path.isabs(rhs_name):
+ rhs_path = _os.path.join(rhs_root.absolute, rhs_root[rhs_name])
return _filecmp.cmp(lhs_path, rhs_path, shallow=False)
src_root = Base(".") if src_root is None else src_root
dst_root = Base(".") if dst_root is None else dst_root
mkdir(dst_root, _os.path.dirname(dst_name))
- src_path = _os.path.join(src_root.absolute, src_root[src_name])
- dst_path = _os.path.join(dst_root.absolute, dst_root[dst_name])
+ (src_path, dst_path) = (src_name, dst_name)
+ if not _os.path.isabs(src_name):
+ src_path = _os.path.join(src_root.absolute, src_root[src_name])
+ if not _os.path.isabs(dst_name):
+ dst_path = _os.path.join(dst_root.absolute, dst_root[dst_name])
with _codecs.open(src_path, "rb") as istream:
with _codecs.open(dst_path, "wb") as ostream:
while 1:
def exists(root, name):
"""Check whether the given file exists."""
root = Base(".") if root is None else root
- path = _os.path.join(root.absolute, root[name])
+ path = name if _os.path.isabs(name) else _os.path.join(root.absolute, root[name])
return _os.path.exists(path)
dst_root = Base(".") if dst_root is None else dst_root
mkdir(src_root, _os.path.dirname(src_name))
mkdir(dst_root, _os.path.dirname(dst_name))
- src_path = _os.path.join(src_root.absolute, src_root[src_name])
- dst_path = _os.path.join(dst_root.absolute, dst_root[dst_name])
+ (src_path, dst_path) = (src_name, dst_name)
+ if not _os.path.isabs(src_name):
+ src_path = _os.path.join(src_root.absolute, src_root[src_name])
+ if not _os.path.isabs(dst_name):
+ dst_path = _os.path.join(dst_root.absolute, dst_root[dst_name])
_os.link(src_path, dst_path)
src_root = Base(".") if src_root is None else src_root
dst_root = Base(".") if dst_root is None else dst_root
mkdir(dst_root, _os.path.dirname(dst_name))
- src_path = _os.path.join(src_root.absolute, src_root[src_name])
- dst_path = _os.path.join(dst_root.absolute, dst_root[dst_name])
+ (src_path, dst_path) = (src_name, dst_name)
+ if not _os.path.isabs(src_name):
+ src_path = _os.path.join(src_root.absolute, src_root[src_name])
+ if not _os.path.isabs(dst_name):
+ dst_path = _os.path.join(dst_root.absolute, dst_root[dst_name])
_os.rename(src_path, dst_path)
+def iostream(root, name, mode="r", encoding=None):
+ """Open file and return a stream. Raise IOError upon failure."""
+ root = Base(".") if root is None else root
+ path = name if _os.path.isabs(name) else _os.path.join(root.absolute, root[name])
+ return _codecs.open(path, mode, encoding)
+
+
def readlink(root, name):
"""Obtain the path to which the symbolic link points."""
root = Base(".") if root is None else root
mkdir(root, _os.path.dirname(name))
- path = _os.path.join(root.absolute, root[name])
+ path = name if _os.path.isabs(name) else _os.path.join(root.absolute, root[name])
return _os.readlink(path)
dst_root = Base(".") if dst_root is None else dst_root
mkdir(dst_root, _os.path.dirname(dst_name))
if not relative:
- src_path = _os.path.join(src_root.absolute, src_root[src_name])
- dst_path = _os.path.join(dst_root.absolute, dst_root[dst_name])
+ (src_path, dst_path) = (src_name, dst_name)
+ if not _os.path.isabs(src_name):
+ src_path = _os.path.join(src_root.absolute, src_root[src_name])
+ if not _os.path.isabs(dst_name):
+ dst_path = _os.path.join(dst_root.absolute, dst_root[dst_name])
else:
src_path = _os.path.join(src_root.relative, src_root[src_name])
dst_path = _os.path.join(dst_root.relative, dst_root[dst_name])
"""Unlink a file, backing it up if necessary."""
root = Base(".") if root is None else root
mkdir(root, _os.path.dirname(name))
- path = _os.path.join(root.absolute, root[name])
+ path = name if _os.path.isabs(name) else _os.path.join(root.absolute, root[name])
_os.unlink(path)