Pacman-dev
Threads by month
- ----- 2025 -----
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- 1 participants
- 7242 discussions
02 Nov '18
Provide both build systems in parallel for now, to ensure that we work
out all the differences between the two. Some time from now, we'll give
up on autotools.
Meson tends to be faster and probably easier to read/maintain. On my
machine, the full meson configure+build+install takes a little under
half as long as a similar autotools-based invocation.
Building with meson is a two step process. First, configure the build:
meson build
Then, compile the project:
ninja -C build
There's some mild differences in functionality between meson and
autotools. specifically:
1) No singular update-po target. meson only generates individual
update-po targets for each textdomain (of which we have 3). To make
this easier, there's a build-aux/update-po script which finds all
update-po targets and runs them.
2) No doxygen support. Doxygen seems to be terrible and requires that
everything be built through the Doxyfile. Support for out-of-tree builds
(enforced by meson) appears to be nonexistant. I'd suggest just running
doxygen directly since we never package these files and just export them
for the website.
3) No 'make dist' equivalent. Just run 'git archive' to generate a
suitable tarball for distribution.
---
Yes, this is huge. All 330 tests pass, and I've been building/using
pacman from my 'meson' branch for a while now.
Feedback wanted.
.ycm_extra_conf.py | 250 ++++++++++
build-aux/edit-script.sh.in | 33 ++
build-aux/meson-make-symlink.sh | 12 +
build-aux/tap-driver.py | 296 +++++++++++
build-aux/update-po | 39 ++
doc/meson.build | 118 +++++
lib/libalpm/meson.build | 33 ++
lib/libalpm/po/meson.build | 15 +
meson.build | 487 +++++++++++++++++++
meson_options.txt | 58 +++
scripts/libmakepkg/integrity/meson.build | 20 +
scripts/libmakepkg/lint_config/meson.build | 18 +
scripts/libmakepkg/lint_package/meson.build | 20 +
scripts/libmakepkg/lint_pkgbuild/meson.build | 37 ++
scripts/libmakepkg/meson.build | 31 ++
scripts/libmakepkg/source/meson.build | 22 +
scripts/libmakepkg/tidy/meson.build | 23 +
scripts/libmakepkg/util/meson.build | 24 +
scripts/meson.build | 66 +++
scripts/po/meson.build | 15 +
src/common/meson.build | 4 +
src/pacman/meson.build | 23 +
src/pacman/po/meson.build | 15 +
src/util/meson.build | 3 +
test/pacman/meson.build | 357 ++++++++++++++
test/scripts/meson.build | 12 +
test/util/meson.build | 6 +
27 files changed, 2037 insertions(+)
create mode 100644 .ycm_extra_conf.py
create mode 100644 build-aux/edit-script.sh.in
create mode 100644 build-aux/meson-make-symlink.sh
create mode 100644 build-aux/tap-driver.py
create mode 100755 build-aux/update-po
create mode 100644 doc/meson.build
create mode 100644 lib/libalpm/meson.build
create mode 100644 lib/libalpm/po/meson.build
create mode 100644 meson.build
create mode 100644 meson_options.txt
create mode 100644 scripts/libmakepkg/integrity/meson.build
create mode 100644 scripts/libmakepkg/lint_config/meson.build
create mode 100644 scripts/libmakepkg/lint_package/meson.build
create mode 100644 scripts/libmakepkg/lint_pkgbuild/meson.build
create mode 100644 scripts/libmakepkg/meson.build
create mode 100644 scripts/libmakepkg/source/meson.build
create mode 100644 scripts/libmakepkg/tidy/meson.build
create mode 100644 scripts/libmakepkg/util/meson.build
create mode 100644 scripts/meson.build
create mode 100644 scripts/po/meson.build
create mode 100644 src/common/meson.build
create mode 100644 src/pacman/meson.build
create mode 100644 src/pacman/po/meson.build
create mode 100644 src/util/meson.build
create mode 100644 test/pacman/meson.build
create mode 100644 test/scripts/meson.build
create mode 100644 test/util/meson.build
diff --git a/.ycm_extra_conf.py b/.ycm_extra_conf.py
new file mode 100644
index 00000000..f297deef
--- /dev/null
+++ b/.ycm_extra_conf.py
@@ -0,0 +1,250 @@
+#!/usr/bin/env python
+
+# SPDX-License-Identifier: Unlicense
+#
+# Based on the template file provided by the 'YCM-Generator' project authored by
+# Reuben D'Netto.
+# Jiahui Xie has re-reformatted and expanded the original script in accordance
+# to the requirements of the PEP 8 style guide and 'systemd' project,
+# respectively.
+#
+# The original license is preserved as it is.
+#
+#
+# This is free and unencumbered software released into the public domain.
+#
+# Anyone is free to copy, modify, publish, use, compile, sell, or
+# distribute this software, either in source code form or as a compiled
+# binary, for any purpose, commercial or non-commercial, and by any
+# means.
+#
+# In jurisdictions that recognize copyright laws, the author or authors
+# of this software dedicate any and all copyright interest in the
+# software to the public domain. We make this dedication for the benefit
+# of the public at large and to the detriment of our heirs and
+# successors. We intend this dedication to be an overt act of
+# relinquishment in perpetuity of all present and future rights to this
+# software under copyright law.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+# IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+# OTHER DEALINGS IN THE SOFTWARE.
+#
+# For more information, please refer to <http://unlicense.org/>
+
+"""
+YouCompleteMe configuration file tailored to support the 'meson' build system
+used by the 'systemd' project.
+"""
+
+import glob
+import os
+import ycm_core
+
+
+SOURCE_EXTENSIONS = (".C", ".cpp", ".cxx", ".cc", ".c", ".m", ".mm")
+HEADER_EXTENSIONS = (".H", ".h", ".hxx", ".hpp", ".hh")
+
+
+def DirectoryOfThisScript():
+ """
+ Return the absolute path of the parent directory containing this
+ script.
+ """
+ return os.path.dirname(os.path.abspath(__file__))
+
+
+def GuessBuildDirectory():
+ """
+ Guess the build directory using the following heuristics:
+
+ 1. Returns the current directory of this script plus 'build'
+ subdirectory in absolute path if this subdirectory exists.
+
+ 2. Otherwise, probes whether there exists any directory
+ containing '.ninja_log' file two levels above the current directory;
+ returns this single directory only if there is one candidate.
+ """
+ result = os.path.join(DirectoryOfThisScript(), "build")
+
+ if os.path.exists(result):
+ return result
+
+ result = glob.glob(os.path.join(DirectoryOfThisScript(),
+ "..", "..", "*", ".ninja_log"))
+
+ if not result:
+ return ""
+
+ if 1 != len(result):
+ return ""
+
+ return os.path.split(result[0])[0]
+
+
+def TraverseByDepth(root, include_extensions):
+ """
+ Return a set of child directories of the 'root' containing file
+ extensions specified in 'include_extensions'.
+
+ NOTE:
+ 1. The 'root' directory itself is excluded from the result set.
+ 2. No subdirectories would be excluded if 'include_extensions' is left
+ to 'None'.
+ 3. Each entry in 'include_extensions' must begin with string '.'.
+ """
+ is_root = True
+ result = set()
+ # Perform a depth first top down traverse of the given directory tree.
+ for root_dir, subdirs, file_list in os.walk(root):
+ if not is_root:
+ # print("Relative Root: ", root_dir)
+ # print(subdirs)
+ if include_extensions:
+ get_ext = os.path.splitext
+ subdir_extensions = {
+ get_ext(f)[-1] for f in file_list if get_ext(f)[-1]
+ }
+ if subdir_extensions & include_extensions:
+ result.add(root_dir)
+ else:
+ result.add(root_dir)
+ else:
+ is_root = False
+
+ return result
+
+
+_project_src_dir = os.path.join(DirectoryOfThisScript(), "src")
+_include_dirs_set = TraverseByDepth(_project_src_dir, frozenset({".h"}))
+flags = [
+ "-x",
+ "c"
+ # The following flags are partially redundant due to the existence of
+ # 'compile_commands.json'.
+ # '-Wall',
+ # '-Wextra',
+ # '-Wfloat-equal',
+ # '-Wpointer-arith',
+ # '-Wshadow',
+ # '-std=gnu99',
+]
+
+for include_dir in _include_dirs_set:
+ flags.append("-I" + include_dir)
+
+# Set this to the absolute path to the folder (NOT the file!) containing the
+# compile_commands.json file to use that instead of 'flags'. See here for
+# more details: http://clang.llvm.org/docs/JSONCompilationDatabase.html
+#
+# You can get CMake to generate this file for you by adding:
+# set( CMAKE_EXPORT_COMPILE_COMMANDS 1 )
+# to your CMakeLists.txt file.
+#
+# Most projects will NOT need to set this to anything; you can just change the
+# 'flags' list of compilation flags. Notice that YCM itself uses that approach.
+compilation_database_folder = GuessBuildDirectory()
+
+if os.path.exists(compilation_database_folder):
+ database = ycm_core.CompilationDatabase(compilation_database_folder)
+else:
+ database = None
+
+
+def MakeRelativePathsInFlagsAbsolute(flags, working_directory):
+ """
+ Iterate through 'flags' and replace the relative paths prefixed by
+ '-isystem', '-I', '-iquote', '--sysroot=' with absolute paths
+ start with 'working_directory'.
+ """
+ if not working_directory:
+ return list(flags)
+ new_flags = []
+ make_next_absolute = False
+ path_flags = ["-isystem", "-I", "-iquote", "--sysroot="]
+ for flag in flags:
+ new_flag = flag
+
+ if make_next_absolute:
+ make_next_absolute = False
+ if not flag.startswith("/"):
+ new_flag = os.path.join(working_directory, flag)
+
+ for path_flag in path_flags:
+ if flag == path_flag:
+ make_next_absolute = True
+ break
+
+ if flag.startswith(path_flag):
+ path = flag[len(path_flag):]
+ new_flag = path_flag + os.path.join(working_directory, path)
+ break
+
+ if new_flag:
+ new_flags.append(new_flag)
+ return new_flags
+
+
+def IsHeaderFile(filename):
+ """
+ Check whether 'filename' is considered as a header file.
+ """
+ extension = os.path.splitext(filename)[1]
+ return extension in HEADER_EXTENSIONS
+
+
+def GetCompilationInfoForFile(filename):
+ """
+ Helper function to look up compilation info of 'filename' in the 'database'.
+ """
+ # The compilation_commands.json file generated by CMake does not have
+ # entries for header files. So we do our best by asking the db for flags for
+ # a corresponding source file, if any. If one exists, the flags for that
+ # file should be good enough.
+ if not database:
+ return None
+
+ if IsHeaderFile(filename):
+ basename = os.path.splitext(filename)[0]
+ for extension in SOURCE_EXTENSIONS:
+ replacement_file = basename + extension
+ if os.path.exists(replacement_file):
+ compilation_info = \
+ database.GetCompilationInfoForFile(replacement_file)
+ if compilation_info.compiler_flags_:
+ return compilation_info
+ return None
+ return database.GetCompilationInfoForFile(filename)
+
+
+def FlagsForFile(filename, **kwargs):
+ """
+ Callback function to be invoked by YouCompleteMe in order to get the
+ information necessary to compile 'filename'.
+
+ It returns a dictionary with a single element 'flags'. This element is a
+ list of compiler flags to pass to libclang for the file 'filename'.
+ """
+ if database:
+ # Bear in mind that compilation_info.compiler_flags_ does NOT return a
+ # python list, but a "list-like" StringVec object
+ compilation_info = GetCompilationInfoForFile(filename)
+ if not compilation_info:
+ return None
+
+ final_flags = MakeRelativePathsInFlagsAbsolute(
+ compilation_info.compiler_flags_,
+ compilation_info.compiler_working_dir_)
+
+ else:
+ relative_to = DirectoryOfThisScript()
+ final_flags = MakeRelativePathsInFlagsAbsolute(flags, relative_to)
+
+ return {
+ "flags": final_flags,
+ "do_cache": True
+ }
diff --git a/build-aux/edit-script.sh.in b/build-aux/edit-script.sh.in
new file mode 100644
index 00000000..3e3a1b6a
--- /dev/null
+++ b/build-aux/edit-script.sh.in
@@ -0,0 +1,33 @@
+#!@BASH@
+
+input=$1
+output=$2
+mode=$3
+
+"@SED@" \
+ -e "s|@rootdir[@]|@ROOTDIR@|g" \
+ -e "s|@localedir[@]|@LOCALEDIR@|g" \
+ -e "s|@sysconfdir[@]|@sysconfdir@|g" \
+ -e "s|@localstatedir[@]|@localstatedir@|g" \
+ -e "s|@libmakepkgdir[@]|@LIBMAKEPKGDIR@|g" \
+ -e "s|@pkgdatadir[@]|@PKGDATADIR@|g" \
+ -e "s|@prefix[@]|@PREFIX@|g" \
+ -e "1s|#!/bin/bash|#!@BASH@|g" \
+ -e "s|@PACKAGE_VERSION[@]|@PACKAGE_VERSION@|g" \
+ -e "s|@PACKAGE_NAME[@]|@PACKAGE_NAME@|g" \
+ -e "s|@BUILDSCRIPT[@]|@BUILDSCRIPT@|g" \
+ -e "s|@TEMPLATE_DIR[@]|@TEMPLATE_DIR@|g" \
+ -e "s|@DEBUGSUFFIX[@]|@DEBUGSUFFIX@|g" \
+ -e "s|@INODECMD[@]|@INODECMD@|g" \
+ -e "s|@OWNERCMD[@]|@OWNERCMD@|g" \
+ -e "s|@MODECMD[@]|@MODECMD@|g" \
+ -e "s|@SEDINPLACEFLAGS[@]|@SEDINPLACEFLAGS@|g" \
+ -e "s|@SEDPATH[@]|@SEDPATH@|g" \
+ -e "s|@DUFLAGS[@]|@DUFLAGS@|g" \
+ -e "s|@DUPATH[@]|@DUPATH@|g" \
+ -e "s|@configure_input[@]|Generated from ${output##*/}.sh.in; do not edit by hand.|g" \
+ "$input" >"$output"
+
+if [[ $mode ]]; then
+ chmod "$mode" "$output"
+fi
diff --git a/build-aux/meson-make-symlink.sh b/build-aux/meson-make-symlink.sh
new file mode 100644
index 00000000..501cd43d
--- /dev/null
+++ b/build-aux/meson-make-symlink.sh
@@ -0,0 +1,12 @@
+#!/bin/sh
+set -eu
+
+# this is needed mostly because $DESTDIR is provided as a variable,
+# and we need to create the target directory...
+
+mkdir -vp "$(dirname "${DESTDIR:-}$2")"
+if [ "$(dirname $1)" = . ]; then
+ ln -vfs -T "$1" "${DESTDIR:-}$2"
+else
+ ln -vfs -T --relative "${DESTDIR:-}$1" "${DESTDIR:-}$2"
+fi
diff --git a/build-aux/tap-driver.py b/build-aux/tap-driver.py
new file mode 100644
index 00000000..c231caec
--- /dev/null
+++ b/build-aux/tap-driver.py
@@ -0,0 +1,296 @@
+#!/usr/bin/env python3
+# Adapted from tappy copyright (c) 2016, Matt Layman
+# MIT license
+# https://github.com/python-tap/tappy
+
+import io
+import re
+import subprocess
+import sys
+
+
+class Directive(object):
+ """A representation of a result line directive."""
+
+ skip_pattern = re.compile(
+ r"""^SKIP\S*
+ (?P<whitespace>\s*) # Optional whitespace.
+ (?P<reason>.*) # Slurp up the rest.""",
+ re.IGNORECASE | re.VERBOSE)
+ todo_pattern = re.compile(
+ r"""^TODO\b # The directive name
+ (?P<whitespace>\s*) # Immediately following must be whitespace.
+ (?P<reason>.*) # Slurp up the rest.""",
+ re.IGNORECASE | re.VERBOSE)
+
+ def __init__(self, text):
+ """Initialize the directive by parsing the text.
+ The text is assumed to be everything after a '#\s*' on a result line.
+ """
+ self._text = text
+ self._skip = False
+ self._todo = False
+ self._reason = None
+
+ match = self.skip_pattern.match(text)
+ if match:
+ self._skip = True
+ self._reason = match.group('reason')
+
+ match = self.todo_pattern.match(text)
+ if match:
+ if match.group('whitespace'):
+ self._todo = True
+ else:
+ # Catch the case where the directive has no descriptive text.
+ if match.group('reason') == '':
+ self._todo = True
+ self._reason = match.group('reason')
+
+ @property
+ def text(self):
+ """Get the entire text."""
+ return self._text
+
+ @property
+ def skip(self):
+ """Check if the directive is a SKIP type."""
+ return self._skip
+
+ @property
+ def todo(self):
+ """Check if the directive is a TODO type."""
+ return self._todo
+
+ @property
+ def reason(self):
+ """Get the reason for the directive."""
+ return self._reason
+
+
+class Parser(object):
+ """A parser for TAP files and lines."""
+
+ # ok and not ok share most of the same characteristics.
+ result_base = r"""
+ \s* # Optional whitespace.
+ (?P<number>\d*) # Optional test number.
+ \s* # Optional whitespace.
+ (?P<description>[^#]*) # Optional description before #.
+ \#? # Optional directive marker.
+ \s* # Optional whitespace.
+ (?P<directive>.*) # Optional directive text.
+ """
+ ok = re.compile(r'^ok' + result_base, re.VERBOSE)
+ not_ok = re.compile(r'^not\ ok' + result_base, re.VERBOSE)
+ plan = re.compile(r"""
+ ^1..(?P<expected>\d+) # Match the plan details.
+ [^#]* # Consume any non-hash character to confirm only
+ # directives appear with the plan details.
+ \#? # Optional directive marker.
+ \s* # Optional whitespace.
+ (?P<directive>.*) # Optional directive text.
+ """, re.VERBOSE)
+ diagnostic = re.compile(r'^#')
+ bail = re.compile(r"""
+ ^Bail\ out!
+ \s* # Optional whitespace.
+ (?P<reason>.*) # Optional reason.
+ """, re.VERBOSE)
+ version = re.compile(r'^TAP version (?P<version>\d+)$')
+
+ TAP_MINIMUM_DECLARED_VERSION = 13
+
+ def parse(self, fh):
+ """Generate tap.line.Line objects, given a file-like object `fh`.
+ `fh` may be any object that implements both the iterator and
+ context management protocol (i.e. it can be used in both a
+ "with" statement and a "for...in" statement.)
+ Trailing whitespace and newline characters will be automatically
+ stripped from the input lines.
+ """
+ with fh:
+ for line in fh:
+ yield self.parse_line(line.rstrip())
+
+ def parse_line(self, text):
+ """Parse a line into whatever TAP category it belongs."""
+ match = self.ok.match(text)
+ if match:
+ return self._parse_result(True, match)
+
+ match = self.not_ok.match(text)
+ if match:
+ return self._parse_result(False, match)
+
+ if self.diagnostic.match(text):
+ return ('diagnostic', text)
+
+ match = self.plan.match(text)
+ if match:
+ return self._parse_plan(match)
+
+ match = self.bail.match(text)
+ if match:
+ return ('bail', match.group('reason'))
+
+ match = self.version.match(text)
+ if match:
+ return self._parse_version(match)
+
+ return ('unknown',)
+
+ def _parse_plan(self, match):
+ """Parse a matching plan line."""
+ expected_tests = int(match.group('expected'))
+ directive = Directive(match.group('directive'))
+
+ # Only SKIP directives are allowed in the plan.
+ if directive.text and not directive.skip:
+ return ('unknown',)
+
+ return ('plan', expected_tests, directive)
+
+ def _parse_result(self, ok, match):
+ """Parse a matching result line into a result instance."""
+ return ('result', ok, match.group('number'),
+ match.group('description').strip(),
+ Directive(match.group('directive')))
+
+ def _parse_version(self, match):
+ version = int(match.group('version'))
+ if version < self.TAP_MINIMUM_DECLARED_VERSION:
+ raise ValueError('It is an error to explicitly specify '
+ 'any version lower than 13.')
+ return ('version', version)
+
+
+class Rules(object):
+
+ def __init__(self):
+ self._lines_seen = {'plan': [], 'test': 0, 'failed': 0, 'version': []}
+ self._errors = []
+
+ def check(self, final_line_count):
+ """Check the status of all provided data and update the suite."""
+ if self._lines_seen['version']:
+ self._process_version_lines()
+ self._process_plan_lines(final_line_count)
+
+ def check_errors(self):
+ if self._lines_seen['failed'] > 0:
+ self._add_error('Tests failed.')
+ if self._errors:
+ for error in self._errors:
+ print(error)
+ return 1
+ return 0
+
+ def _process_version_lines(self):
+ """Process version line rules."""
+ if len(self._lines_seen['version']) > 1:
+ self._add_error('Multiple version lines appeared.')
+ elif self._lines_seen['version'][0] != 1:
+ self._add_error('The version must be on the first line.')
+
+ def _process_plan_lines(self, final_line_count):
+ """Process plan line rules."""
+ if not self._lines_seen['plan']:
+ self._add_error('Missing a plan.')
+ return
+
+ if len(self._lines_seen['plan']) > 1:
+ self._add_error('Only one plan line is permitted per file.')
+ return
+
+ expected_tests, at_line = self._lines_seen['plan'][0]
+ if not self._plan_on_valid_line(at_line, final_line_count):
+ self._add_error(
+ 'A plan must appear at the beginning or end of the file.')
+ return
+
+ if expected_tests != self._lines_seen['test']:
+ self._add_error(
+ 'Expected {expected_count} tests '
+ 'but only {seen_count} ran.'.format(
+ expected_count=expected_tests,
+ seen_count=self._lines_seen['test']))
+
+ def _plan_on_valid_line(self, at_line, final_line_count):
+ """Check if a plan is on a valid line."""
+ # Put the common cases first.
+ if at_line == 1 or at_line == final_line_count:
+ return True
+
+ # The plan may only appear on line 2 if the version is at line 1.
+ after_version = (
+ self._lines_seen['version'] and
+ self._lines_seen['version'][0] == 1 and
+ at_line == 2)
+ if after_version:
+ return True
+
+ return False
+
+ def handle_bail(self, reason):
+ """Handle a bail line."""
+ self._add_error('Bailed: {reason}').format(reason=reason)
+
+ def handle_skipping_plan(self):
+ """Handle a plan that contains a SKIP directive."""
+ sys.exit(77)
+
+ def saw_plan(self, expected_tests, at_line):
+ """Record when a plan line was seen."""
+ self._lines_seen['plan'].append((expected_tests, at_line))
+
+ def saw_test(self, ok):
+ """Record when a test line was seen."""
+ self._lines_seen['test'] += 1
+ if not ok:
+ self._lines_seen['failed'] += 1
+
+ def saw_version_at(self, line_counter):
+ """Record when a version line was seen."""
+ self._lines_seen['version'].append(line_counter)
+
+ def _add_error(self, message):
+ self._errors += [message]
+
+
+if __name__ == '__main__':
+ parser = Parser()
+ rules = Rules()
+
+ try:
+ out = subprocess.check_output(sys.argv[1:], universal_newlines=True)
+ except subprocess.CalledProcessError as e:
+ sys.stdout.write(e.output)
+ raise e
+
+ line_generator = parser.parse(io.StringIO(out))
+ line_counter = 0
+ for line in line_generator:
+ line_counter += 1
+
+ if line[0] == 'unknown':
+ continue
+
+ if line[0] == 'result':
+ rules.saw_test(line[1])
+ print('{okay} {num} {description} {directive}'.format(
+ okay=('' if line[1] else 'not ') + 'ok', num=line[2],
+ description=line[3], directive=line[4].text))
+ elif line[0] == 'plan':
+ if line[2].skip:
+ rules.handle_skipping_plan()
+ rules.saw_plan(line[1], line_counter)
+ elif line[0] == 'bail':
+ rules.handle_bail(line[1])
+ elif line[0] == 'version':
+ rules.saw_version_at(line_counter)
+ elif line[0] == 'diagnostic':
+ print(line[1])
+
+ rules.check(line_counter)
+ sys.exit(rules.check_errors())
diff --git a/build-aux/update-po b/build-aux/update-po
new file mode 100755
index 00000000..ce1ad4be
--- /dev/null
+++ b/build-aux/update-po
@@ -0,0 +1,39 @@
+#!/bin/bash
+
+find_build_directory() {
+ local build_dirs=(*/.ninja_log)
+
+ if [[ ! -e ${build_dirs[0]} ]]; then
+ echo "error: No build directory found. Have you run 'meson build' yet?" >&2
+ return 1
+ elif (( ${#build_dirs[*]} > 1 )); then
+ echo "error: Multiple build directories found. Unable to proceed." >&2
+ return 1
+ fi
+
+ printf '%s\n' "${build_dirs[0]%/*}"
+}
+
+
+filter_targets_by_name() {
+ if command -v jq &>/dev/null; then
+ jq --arg re "$1" -r 'map(.name)[] | select(match($re))'
+ else
+ json_pp | awk -v filter="$1" -F'[:"]' \
+ '$2 == "name" && $(NF - 1) ~ filter { print $(NF - 1) }'
+ fi
+}
+
+# Make things simple and require that we're in the build root rather than
+# trying to chase down the location of this script and the relative build dir.
+if [[ ! -d .git ]]; then
+ echo "This script must be run from the root of the repository" >&2
+ exit 1
+fi
+
+build_dir=$(find_build_directory) || exit 1
+
+mapfile -t targets < \
+ <(meson introspect "$build_dir" --targets | filter_targets_by_name "-update-po$")
+
+ninja -C "$build_dir" "${targets[@]}"
diff --git a/doc/meson.build b/doc/meson.build
new file mode 100644
index 00000000..b1ffd793
--- /dev/null
+++ b/doc/meson.build
@@ -0,0 +1,118 @@
+manpages = [
+ { 'name': 'alpm-hooks.5' },
+ { 'name': 'pacman.8' },
+ { 'name': 'makepkg.8' },
+ { 'name': 'makepkg-template.1' },
+ { 'name': 'repo-add.8' },
+ { 'name': 'vercmp.8' },
+ { 'name': 'pkgdelta.8' },
+ { 'name': 'pacman-key.8' },
+ { 'name': 'PKGBUILD.5', 'extra_depends' : [ 'PKGBUILD-example.txt' ] },
+ { 'name': 'makepkg.conf.5' },
+ { 'name': 'pacman.conf.5' },
+ { 'name': 'libalpm.3' },
+ { 'name': 'BUILDINFO.5' },
+]
+
+asciidoc_conf = join_paths(meson.current_source_dir(), 'asciidoc.conf')
+
+asciidoc_opts = [
+ '-f', asciidoc_conf,
+ '-a', 'pacman_version="@0@"'.format(PACKAGE_VERSION),
+ '-a', 'pacman_date=@0@'.format(run_command('date', '+%Y-%m-%d').stdout().strip()),
+ '-a', 'pkgdatadir=@0@'.format(PKGDATADIR),
+ '-a', 'localstatedir=@0@'.format(LOCALSTATEDIR),
+ '-a', 'sysconfdir=@0@'.format(SYSCONFDIR),
+ '-a', 'datarootdir=@0@'.format(DATAROOTDIR),
+]
+
+html_targets = []
+html_files = []
+
+foreach page : manpages
+ manpage = page['name']
+ htmlpage = '@0@.html'.format(manpage)
+ input = '@0@.asciidoc'.format(manpage)
+
+ section = page['name'].split('.')[-1]
+
+ mandirn = join_paths(MANDIR, 'man' + section)
+
+ custom_target(
+ manpage,
+ command : [
+ A2X,
+ '--no-xmllint',
+ '-d', 'manpage',
+ '-f', 'manpage',
+ '--xsltproc-opts', '-param man.endnotes.list.enabled 0 -param man.endnotes.are.numbered 0',
+ '-D', '@OUTDIR@',
+ '--asciidoc-opts', ' '.join(asciidoc_opts),
+ '@INPUT@',
+ ],
+ input : input,
+ output : [manpage],
+ depend_files : [
+ asciidoc_conf,
+ ] + page.get('extra_depends', []),
+ install : true,
+ install_dir : mandirn,
+ )
+
+ html = custom_target(
+ htmlpage,
+ command : [
+ ASCIIDOC,
+ ] + asciidoc_opts + [
+ '-a', 'linkcss',
+ '-a', 'toc',
+ '-a', 'icons',
+ '-a', 'max-width=960px',
+ '-a', 'stylesheet=asciidoc-override.css',
+ '-o', '@OUTPUT@',
+ '@INPUT@',
+ ],
+ input : input,
+ output : [htmlpage],
+ depend_files : [
+ asciidoc_conf,
+ 'asciidoc-override.css',
+ ] + page.get('extra_depends', []),
+ build_by_default : false,
+ install : false,
+ )
+ html_targets += [html]
+ html_files += [htmlpage]
+endforeach
+
+run_target('html',
+ command : ['/bin/true'],
+ depends : html_targets)
+
+custom_target(
+ 'website.tar.gz',
+ command : [
+ 'bsdtar', 'czf', '@OUTPUT@',
+ '-C', meson.current_build_dir(),
+ ] + html_files + [
+ '-C', meson.current_source_dir(),
+ 'submitting-patches.html',
+ 'translation-help.html',
+ 'HACKING.html',
+ 'index.html',
+ 'asciidoc-override.css',
+ '-C', '/etc/asciidoc/stylesheets/',
+ 'asciidoc.css',
+ '-C', '/etc/asciidoc/javascripts/',
+ 'asciidoc.js',
+ '-C', '/etc/asciidoc/',
+ 'images',
+ ],
+ output : ['website.tar.gz'],
+ build_by_default : false,
+ depends : html_targets,
+)
+
+meson.add_install_script(MESON_MAKE_SYMLINK,
+ 'repo-add.8',
+ join_paths(MANDIR, 'man8/repo-remove.8'))
diff --git a/lib/libalpm/meson.build b/lib/libalpm/meson.build
new file mode 100644
index 00000000..84c3dde3
--- /dev/null
+++ b/lib/libalpm/meson.build
@@ -0,0 +1,33 @@
+libalpm_sources = files('''
+ add.h add.c
+ alpm.h alpm.c
+ alpm_list.h alpm_list.c
+ backup.h backup.c
+ base64.h base64.c
+ be_local.c
+ be_package.c
+ be_sync.c
+ conflict.h conflict.c
+ db.h db.c
+ delta.h delta.c
+ deps.h deps.c
+ diskspace.h diskspace.c
+ dload.h dload.c
+ error.c
+ filelist.h filelist.c
+ graph.h graph.c
+ group.h group.c
+ handle.h handle.c
+ hook.h hook.c
+ libarchive-compat.h
+ log.h log.c
+ package.h package.c
+ pkghash.h pkghash.c
+ rawstr.c
+ remove.h remove.c
+ signing.c signing.h
+ sync.h sync.c
+ trans.h trans.c
+ util.h util.c
+ version.c
+'''.split())
diff --git a/lib/libalpm/po/meson.build b/lib/libalpm/po/meson.build
new file mode 100644
index 00000000..cec28a15
--- /dev/null
+++ b/lib/libalpm/po/meson.build
@@ -0,0 +1,15 @@
+i18n.gettext(
+ 'libalpm',
+ args : [
+ '--directory=@0@'.format(meson.current_source_dir()),
+ '--msgid-bugs-address=http://bugs.archlinux.org/index.php?project=3',
+ '--copyright-holder="Pacman Development Team <pacman-dev(a)archlinux.org>"',
+ '--language', 'c',
+
+ '--keyword=_',
+ '--flag=_:1:c-format',
+
+ '--keyword=_n:1,2',
+ '--flag=_n:1:c-format',
+ '--flag=_n:2:c-format',
+ ])
diff --git a/meson.build b/meson.build
new file mode 100644
index 00000000..3f9b2ae0
--- /dev/null
+++ b/meson.build
@@ -0,0 +1,487 @@
+project('pacman',
+ 'c',
+ version : '5.1.0',
+ license : 'GPLv2+',
+ default_options : [
+ 'c_std=gnu99',
+ 'prefix=/usr',
+ 'sysconfdir=/etc',
+ 'localstatedir=/var',
+ ],
+ meson_version : '>= 0.47')
+
+libalpm_version = '11.0.1'
+
+cc = meson.get_compiler('c')
+
+# commandline options
+PREFIX = get_option('prefix')
+DATAROOTDIR = join_paths(PREFIX, get_option('datarootdir'))
+SYSCONFDIR = join_paths(PREFIX, get_option('sysconfdir'))
+LOCALSTATEDIR = join_paths(PREFIX, get_option('localstatedir'))
+LOCALEDIR = join_paths(PREFIX, get_option('localedir'))
+ROOTDIR = get_option('root-dir')
+BINDIR = join_paths(PREFIX, get_option('bindir'))
+MANDIR = join_paths(PREFIX, get_option('mandir'))
+BUILDSCRIPT = get_option('buildscript')
+LIBMAKEPKGDIR = join_paths(PREFIX, DATAROOTDIR, 'makepkg')
+PKGDATADIR = join_paths(PREFIX, DATAROOTDIR, meson.project_name())
+
+PYTHON = find_program('python')
+M4 = find_program('m4')
+SED = find_program('sed')
+DU = find_program('du')
+LDCONFIG = get_option('ldconfig')
+MESON_MAKE_SYMLINK = join_paths(meson.source_root(), 'build-aux/meson-make-symlink.sh')
+
+BASH = find_program('bash4', 'bash')
+if BASH.found()
+ bash_version = run_command(BASH, '-c', 'IFS=.; echo "${BASH_VERSINFO[*]:0:3}"').stdout()
+
+ have_bash = bash_version.version_compare('>= 4.4.0')
+endif
+if not have_bash
+ error('bash >= 4.4.0 is required for pacman scripts.')
+endif
+
+bashcompletion = dependency('bash-completion', required : false)
+if bashcompletion.found()
+ BASHCOMPDIR = bashcompletion.get_pkgconfig_variable('completionsdir')
+else
+ BASHCOMPDIR = join_paths(DATAROOTDIR, 'bash-completion/completions')
+endif
+
+if get_option('use-git-version')
+ PACKAGE_VERSION = run_command(
+ find_program('git'),
+ 'describe',
+ '--abbrev=4',
+ '--dirty').stdout().strip().strip('v')
+else
+ PACKAGE_VERSION = meson.project_version()
+endif
+
+conf = configuration_data()
+conf.set('_GNU_SOURCE', true)
+conf.set_quoted('PACKAGE', meson.project_name())
+conf.set_quoted('PACKAGE_VERSION', PACKAGE_VERSION)
+conf.set_quoted('LOCALEDIR', LOCALEDIR)
+conf.set_quoted('SCRIPTLET_SHELL', get_option('scriptlet-shell'))
+conf.set_quoted('LDCONFIG', LDCONFIG)
+conf.set_quoted('LIB_VERSION', meson.project_version())
+conf.set_quoted('SYSHOOKDIR', join_paths(DATAROOTDIR, 'libalpm/hooks/'))
+conf.set_quoted('CONFFILE', join_paths(SYSCONFDIR, 'pacman.conf'))
+conf.set_quoted('DBPATH', join_paths(LOCALSTATEDIR, 'lib/pacman'))
+conf.set_quoted('GPGDIR', join_paths(SYSCONFDIR, 'pacman.d/gnupg'))
+conf.set_quoted('LOGFILE', join_paths(LOCALSTATEDIR, 'log/pacman.log'))
+conf.set_quoted('CACHEDIR', join_paths(LOCALSTATEDIR, 'cache/pacman/pkg'))
+conf.set_quoted('HOOKDIR', join_paths(SYSCONFDIR, 'pacman.d/hooks/'))
+conf.set_quoted('ROOTDIR', ROOTDIR)
+
+if get_option('i18n')
+ if not cc.has_function('ngettext')
+ error('ngettext not found but NLS support requested')
+ endif
+ conf.set('ENABLE_NLS', 1)
+endif
+
+# dependencies
+libarchive = dependency('libarchive',
+ version : '>=3.0.0',
+ static : get_option('buildstatic'))
+
+libcurl = dependency('libcurl',
+ version : '>=7.32.0',
+ required : get_option('curl'),
+ static : get_option('buildstatic'))
+conf.set('HAVE_LIBCURL', libcurl.found())
+
+want_gpgme = get_option('gpgme')
+gpgme_config = find_program('gpgme-config', required : want_gpgme)
+if not want_gpgme.disabled() and gpgme_config.found()
+ gpgme_version = run_command(gpgme_config, '--version').stdout().strip()
+
+ needed_gpgme_version = '>=1.3.0'
+ have = gpgme_version.version_compare(needed_gpgme_version)
+ if want_gpgme.enabled() and not have
+ error('gpgme @0@ is needed for GPG signature support'.format(needed_gpgme_version))
+ endif
+
+ gpgme_libs = [
+ cc.find_library('gpgme', required : have,
+ dirs : [get_option('gpgme-libdir')]),
+ cc.find_library('gpg-error', required : have,
+ dirs : [get_option('gpgme-libdir')]),
+ cc.find_library('assuan', required : have,
+ dirs : [get_option('gpgme-libdir')]),
+ ]
+
+ conf.set('HAVE_LIBGPGME', have)
+else
+ gpgme_libs = []
+ conf.set('HAVE_LIBGPGME', false)
+endif
+
+want_crypto = get_option('crypto')
+if want_crypto == 'openssl'
+ libcrypto = dependency('libcrypto', static : get_option('buildstatic'))
+ if not libcrypto.found()
+ error('openssl support requested but not found')
+ endif
+ crypto_provider = libcrypto
+ conf.set10('HAVE_LIBSSL', true)
+elif want_crypto == 'nettle'
+ libnettle = dependency('nettle', static : get_option('buildstatic'))
+ if not libnettle.found()
+ error('nettle support requested but not found')
+ endif
+ crypto_provider = libnettle
+ conf.set10('HAVE_LIBNETTLE', true)
+else
+ error('unhandled crypto value @0@'.format(want_crypto))
+endif
+
+foreach header : [
+ 'mntent.h',
+ 'sys/mnttab.h',
+ 'sys/mount.h',
+ 'sys/param.h',
+ 'sys/statvfs.h',
+ 'sys/types.h',
+ 'sys/ucred.h',
+ 'termios.h',
+ ]
+ if cc.has_header(header)
+ conf.set('HAVE_' + header.underscorify().to_upper(), true)
+ endif
+endforeach
+
+foreach sym : [
+ 'dup2',
+ 'fork',
+ 'getcwd',
+ 'getmntent',
+ 'getmntinfo',
+ 'gettimeofday',
+ 'memmove',
+ 'memset',
+ 'mkdir',
+ 'realpath',
+ 'regcomp',
+ 'rmdir',
+ 'setenv',
+ 'setlocale',
+ 'strcasecmp',
+ 'strchr',
+ 'strcspn',
+ 'strdup',
+ 'strerror',
+ 'strndup',
+ 'strnlen',
+ 'strnlen',
+ 'strrchr',
+ 'strsep',
+ 'strsep',
+ 'strstr',
+ 'strtol',
+ 'swprintf',
+ 'tcflush',
+ 'tcflush',
+ 'uname',
+ 'wcwidth',
+ ]
+ have = cc.has_function(sym, args : '-D_GNU_SOURCE')
+ conf.set10('HAVE_' + sym.to_upper(), have)
+endforeach
+
+foreach member : [
+ ['struct stat', 'st_blksize', '''#include <sys/stat.h>'''],
+ ['struct statvfs', 'f_flag', '''#include <sys/statvfs.h>'''],
+ ['struct statfs', 'f_flags', '''#include <sys/param.h>
+ #include <sys/mount.h>'''],
+ ]
+ have = cc.has_member(member[0], member[1], prefix : member[2])
+ conf.set('HAVE_' + '_'.join([member[0], member[1]]).underscorify().to_upper(), have)
+endforeach
+
+if conf.has('HAVE_STRUCT_STATVFS_F_FLAG')
+ conf.set('FSSTATSTYPE', 'struct statvfs')
+elif conf.has('HAVE_STRUCT_STATFS_F_FLAGS')
+ conf.set('FSSTATSTYPE', 'struct statfs')
+endif
+
+if get_option('buildtype') == 'debug'
+ extra_cflags = [
+ '-Wcast-align',
+ '-Wclobbered',
+ '-Wempty-body',
+ '-Wfloat-equal',
+ '-Wformat-nonliteral',
+ '-Wformat-security',
+ '-Wignored-qualifiers',
+ '-Winit-self',
+ '-Wlogical-op',
+ '-Wmissing-declarations',
+ '-Wmissing-field-initializers',
+ '-Wmissing-parameter-type',
+ '-Wmissing-prototypes',
+ '-Wold-style-declaration',
+ '-Woverride-init',
+ '-Wpointer-arith',
+ '-Wredundant-decls',
+ '-Wshadow',
+ '-Wsign-compare',
+ '-Wstrict-aliasing',
+ '-Wstrict-overflow=5',
+ '-Wstrict-prototypes',
+ '-Wtype-limits',
+ '-Wuninitialized',
+ '-Wunused-but-set-parameter',
+ '-Wunused-parameter',
+ '-Wwrite-strings',
+ ]
+ add_project_arguments(cc.get_supported_arguments(extra_cflags), language : 'c')
+
+ conf.set('PACMAN_DEBUG', 1)
+endif
+
+config_h = configure_file(
+ output : 'config.h',
+ configuration : conf)
+add_project_arguments('-include', 'config.h', language : 'c')
+
+default_duflags = ' -sk --apparent-size'
+default_sedinplaceflags = ' --follow-symlinks -i'
+inodecmd = 'stat -c \'%i %n\''
+ownercmd = 'stat -c \'%u:%g\''
+modecmd = 'stat -c \'%a\''
+strip_binaries = '--strip-all'
+strip_shared = '--strip-unneeded'
+strip_static = '--strip-debug'
+
+os = host_machine.system()
+if os.startswith('darwin')
+ inodecmd = '/usr/bin/stat -f \'%i %n\''
+ ownercmd = '/usr/bin/stat -f \'%u:%g\''
+ modecmd = '/usr/bin/stat -f \'%lp\''
+ default_sedinplaceflags = ' -i \'\''
+ default_duflags = ' -sk'
+ strip_binaries = ''
+ strip_shared = '-s'
+ strip_static = '-s'
+elif os.contains('bsd') or os == 'dragonfly'
+ inodecmd = 'stat -f \'%i %n\''
+ ownercmd = 'stat -f \'%u:%g\''
+ modecmd = 'stat -f \'%lp\''
+ default_sedinplaceflags = ' -i \'\''
+ default_duflags = ' -sk'
+endif
+
+duflags = get_option('duflags')
+if duflags == 'autodetect'
+ duflags = default_duflags
+endif
+
+sedinplaceflags = get_option('sedinplaceflags')
+if sedinplaceflags == 'auto'
+ sedinplaceflags = default_sedinplaceflags
+endif
+
+chost = run_command(cc, '-dumpmachine').stdout().strip()
+carch = chost.split('-')[0]
+
+# annoyingly, we have to maintain two sets of configuration_data which is
+# largely identical, but which distinguishes between quoting needs.
+substs = configuration_data()
+substs.set('SED', SED.path())
+substs.set('M4', M4.path())
+substs.set('CARCH', carch)
+substs.set('CHOST', chost)
+substs.set('PKGEXT', get_option('pkg-ext'))
+substs.set('SRCEXT', get_option('src-ext'))
+substs.set('ROOTDIR', ROOTDIR)
+substs.set('LOCALEDIR', LOCALEDIR)
+substs.set('sysconfdir', SYSCONFDIR)
+substs.set('localstatedir', LOCALSTATEDIR)
+substs.set('PKGDATADIR', PKGDATADIR)
+substs.set('PREFIX', PREFIX)
+substs.set('BASH', BASH.path())
+substs.set('PACKAGE_VERSION', PACKAGE_VERSION)
+substs.set('PACKAGE_NAME', meson.project_name())
+substs.set('BUILDSCRIPT', BUILDSCRIPT)
+substs.set('TEMPLATE_DIR', get_option('makepkg-template-dir'))
+substs.set('DEBUGSUFFIX', get_option('debug-suffix'))
+substs.set('INODECMD', inodecmd)
+substs.set('OWNERCMD', ownercmd)
+substs.set('MODECMD', modecmd)
+substs.set('SEDINPLACEFLAGS', sedinplaceflags)
+substs.set('SEDPATH', SED.path())
+substs.set('DUFLAGS', duflags)
+substs.set('DUPATH', DU.path())
+substs.set('LIBMAKEPKGDIR', LIBMAKEPKGDIR)
+substs.set('STRIP_BINARIES', strip_binaries)
+substs.set('STRIP_SHARED', strip_shared)
+substs.set('STRIP_STATIC', strip_static)
+
+subdir('lib/libalpm')
+subdir('src/common')
+subdir('src/pacman')
+subdir('src/util')
+subdir('scripts')
+
+# Internationalization
+if get_option('i18n')
+ i18n = import('i18n')
+ subdir('lib/libalpm/po')
+ subdir('src/pacman/po')
+ subdir('scripts/po')
+endif
+
+want_doc = get_option('doc')
+ASCIIDOC = find_program('asciidoc', required : want_doc)
+A2X = find_program('a2x', required : want_doc)
+build_doc = A2X.found() and not want_doc.disabled()
+if build_doc
+ subdir('doc')
+endif
+
+libcommon = static_library(
+ 'common',
+ libcommon_sources,
+ install : false)
+
+includes = include_directories('src/common', 'lib/libalpm')
+
+libalpm = library(
+ 'alpm',
+ libalpm_sources,
+ version : libalpm_version,
+ include_directories : includes,
+ dependencies : [crypto_provider, libarchive, libcurl] + gpgme_libs,
+ link_with : [libcommon],
+ install : true)
+
+install_headers(
+ 'lib/libalpm/alpm.h',
+ 'lib/libalpm/alpm_list.h')
+
+# TODO: this is lacking libs.private
+pkgconfig = import('pkgconfig')
+pkgconfig.generate(
+ libalpm,
+ name : 'libalpm',
+ description : 'Arch Linux package management library',
+ version : libalpm_version,
+ url : 'http://www.archlinux.org/pacman/',
+ requires_private : [crypto_provider, libcurl, libarchive])
+
+pacman_bin = executable(
+ 'pacman',
+ pacman_sources,
+ include_directories : includes,
+ link_with : [libalpm, libcommon],
+ dependencies : [libarchive],
+ install : true,
+)
+
+executable(
+ 'pacman-conf',
+ pacman_conf_sources,
+ include_directories : includes,
+ link_with : [libalpm],
+ install : true,
+)
+
+executable(
+ 'cleanupdelta',
+ cleanupdelta_sources,
+ include_directories : includes,
+ link_with : [libalpm],
+ install : true,
+)
+
+executable(
+ 'testpkg',
+ testpkg_sources,
+ include_directories : includes,
+ link_with : [libalpm],
+ install : true,
+)
+
+executable(
+ 'vercmp',
+ vercmp_sources,
+ include_directories : includes,
+ link_with : [libalpm],
+ install : true,
+)
+
+configure_file(
+ input : 'etc/makepkg.conf.in',
+ output : 'makepkg.conf',
+ configuration : substs,
+ install_dir : SYSCONFDIR)
+
+configure_file(
+ input : 'etc/pacman.conf.in',
+ output : 'pacman.conf',
+ configuration : substs,
+ install_dir : SYSCONFDIR)
+
+install_data(
+ 'proto/PKGBUILD-split.proto',
+ 'proto/PKGBUILD-vcs.proto',
+ 'proto/PKGBUILD.proto',
+ 'proto/proto.install',
+ install_dir : join_paths(DATAROOTDIR, 'pacman'))
+
+TEST_ENV = environment()
+TEST_ENV.set('PMTEST_SCRIPTLIB_DIR', join_paths(meson.source_root(), 'scripts/library/'))
+TEST_ENV.set('PMTEST_LIBMAKEPKG_DIR', join_paths(meson.build_root(), 'scripts/libmakepkg/'))
+TEST_ENV.set('PMTEST_UTIL_DIR', meson.build_root() + '/')
+TEST_ENV.set('PMTEST_SCRIPT_DIR', join_paths(meson.build_root(), 'scripts/'))
+
+subdir('test/pacman')
+subdir('test/scripts')
+subdir('test/util')
+
+message('\n '.join([
+ '@0@ @1@'.format(meson.project_name(), meson.project_version()),
+ 'Build information:',
+ ' prefix : @0@'.format(PREFIX),
+ ' sysconfdir : @0@'.format(SYSCONFDIR),
+ ' conf file : @0@'.format(join_paths(SYSCONFDIR, 'pacman.conf')),
+ ' localstatedir : @0@'.format(LOCALSTATEDIR),
+ ' database dir : @0@'.format(join_paths(LOCALSTATEDIR, 'lib/pacman/')),
+ ' cache dir : @0@'.format(join_paths(LOCALSTATEDIR, 'cache/pacman/pkg/')),
+ ' compiler : @0@ @1@'.format(cc.get_id(), cc.version()),
+ '',
+ ' Architecture : @0@'.format(carch),
+ ' Host Type : @0@'.format(chost),
+ ' File inode command : @0@'.format(inodecmd),
+ ' File owner command : @0@'.format(ownercmd),
+ ' File mode command : @0@'.format(modecmd),
+ ' Directory size command : @0@ @1@'.format(DU.path(), duflags),
+ ' In-place sed command : @0@ @1@'.format(SED.path(), sedinplaceflags),
+ ' libalpm version : @0@'.format(libalpm_version),
+ ' pacman version : @0@'.format(PACKAGE_VERSION),
+ '',
+ 'Directory and file information:',
+ ' root working directory : @0@'.format(ROOTDIR),
+ ' package extension : @0@'.format(get_option('pkg-ext')),
+ ' source pkg extension : @0@'.format(get_option('src-ext')),
+ ' build script name : @0@'.format(BUILDSCRIPT),
+ ' template directory : @0@'.format(get_option('makepkg-template-dir')),
+ '',
+ 'Compilation options:',
+ ' i18n support : @0@'.format(get_option('i18n')),
+ ' Build docs : @0@'.format(build_doc),
+ ' debug build : @0@'.format(get_option('buildtype') == 'debug'),
+ ' Use libcurl : @0@'.format(conf.get('HAVE_LIBCURL')),
+ ' Use GPGME : @0@'.format(conf.get('HAVE_LIBGPGME')),
+ ' Use OpenSSL : @0@'.format(conf.has('HAVE_LIBSSL') and
+ conf.get('HAVE_LIBSSL') == 1),
+ ' Use nettle : @0@'.format(conf.has('HAVE_LIBNETTLE') and
+ conf.get('HAVE_LIBNETTLE') == 1),
+ '',
+]))
diff --git a/meson_options.txt b/meson_options.txt
new file mode 100644
index 00000000..9e6e527e
--- /dev/null
+++ b/meson_options.txt
@@ -0,0 +1,58 @@
+# build behavior
+option('use-git-version', type : 'boolean', value : false,
+ description : 'take version information from git')
+option('buildstatic', type : 'boolean', value : false,
+ description : 'if true, build staticly linked binaries')
+
+# directories and filenames
+option('root-dir', type : 'string', value : '/',
+ description : 'set the location of the root operating directory')
+
+option('pkg-ext', type : 'string', value : '.pkg.tar.gz',
+ description : 'set the file extension used by packages')
+
+option('src-ext', type : 'string', value : '.src.tar.gz',
+ description : 'set the file extension used by source packages')
+
+option('scriptlet-shell', type : 'string', value : '/bin/sh',
+ description : 'The full path of the shell used to run install scriptlets')
+
+option('ldconfig', type : 'string', value : '/sbin/ldconfig',
+ description : 'set the full path to ldconfig')
+
+option('buildscript', type : 'string', value : 'PKGBUILD',
+ description : 'set the build script name used by makepkg')
+
+option('datarootdir', type : 'string', value : 'share',
+ description : 'FIXME')
+
+option('makepkg-template-dir', type : 'string', value : '/usr/share/makepkg-template',
+ description : 'template dir used by makepkg-template')
+
+option('debug-suffix', type : 'string', value : 'debug',
+ description : 'suffix for split debugging symbol packages used by makepkg')
+
+# dependencies, features
+option('doc', type : 'feature', value : 'auto',
+ description : 'generate docs and manpages')
+
+option('curl', type : 'feature', value : 'auto',
+ description : 'use curl to download files')
+
+option('crypto', type : 'combo', choices : ['openssl', 'nettle'],
+ description : 'select crypto implementation')
+
+option('gpgme', type : 'feature', value : 'auto',
+ description : 'use GPGME for PGP signature verification')
+option('gpgme-libdir', type : 'string', value : '/usr/lib',
+ description : 'search directory for gpgme libraries.')
+
+option('i18n', type : 'boolean', value : true,
+ description : 'enable localization of pacman, libalpm and scripts')
+
+# tools
+option('duflags', type : 'string', value : 'autodetect',
+ description : 'flags to pass to du to measure file size')
+
+option('sedinplaceflags', type : 'string', value : 'auto',
+ description : 'flags to pass to sed to edit a file in-place')
diff --git a/scripts/libmakepkg/integrity/meson.build b/scripts/libmakepkg/integrity/meson.build
new file mode 100644
index 00000000..9aa9061c
--- /dev/null
+++ b/scripts/libmakepkg/integrity/meson.build
@@ -0,0 +1,20 @@
+libmakepkg_module = 'integrity'
+
+sources = [
+ 'generate_checksum.sh.in',
+ 'generate_signature.sh.in',
+ 'verify_checksum.sh.in',
+ 'verify_signature.sh.in',
+]
+
+foreach src : sources
+ output_dir = join_paths(get_option('datadir'), 'makepkg', libmakepkg_module)
+
+ custom_target(
+ libmakepkg_module + '_' + src.underscorify(),
+ command : [ SCRIPT_EDITOR, '@INPUT@', '@OUTPUT@' ],
+ input : src,
+ output : '@BASENAME@',
+ install : true,
+ install_dir : output_dir)
+endforeach
diff --git a/scripts/libmakepkg/lint_config/meson.build b/scripts/libmakepkg/lint_config/meson.build
new file mode 100644
index 00000000..884d63d7
--- /dev/null
+++ b/scripts/libmakepkg/lint_config/meson.build
@@ -0,0 +1,18 @@
+libmakepkg_module = 'lint_config'
+
+sources = [
+ 'paths.sh.in',
+ 'variable.sh.in',
+]
+
+foreach src : sources
+ output_dir = join_paths(get_option('datadir'), 'makepkg', libmakepkg_module)
+
+ custom_target(
+ libmakepkg_module + '_' + src.underscorify(),
+ command : [ SCRIPT_EDITOR, '@INPUT@', '@OUTPUT@' ],
+ input : src,
+ output : '@BASENAME@',
+ install : true,
+ install_dir : output_dir)
+endforeach
diff --git a/scripts/libmakepkg/lint_package/meson.build b/scripts/libmakepkg/lint_package/meson.build
new file mode 100644
index 00000000..8eb1aaf7
--- /dev/null
+++ b/scripts/libmakepkg/lint_package/meson.build
@@ -0,0 +1,20 @@
+libmakepkg_module = 'lint_package'
+
+sources = [
+ 'build_references.sh.in',
+ 'dotfiles.sh.in',
+ 'file_names.sh.in',
+ 'missing_backup.sh.in',
+]
+
+foreach src : sources
+ output_dir = join_paths(get_option('datadir'), 'makepkg', libmakepkg_module)
+
+ custom_target(
+ libmakepkg_module + '_' + src.underscorify(),
+ command : [ SCRIPT_EDITOR, '@INPUT@', '@OUTPUT@' ],
+ input : src,
+ output : '@BASENAME@',
+ install : true,
+ install_dir : output_dir)
+endforeach
diff --git a/scripts/libmakepkg/lint_pkgbuild/meson.build b/scripts/libmakepkg/lint_pkgbuild/meson.build
new file mode 100644
index 00000000..9067c9d6
--- /dev/null
+++ b/scripts/libmakepkg/lint_pkgbuild/meson.build
@@ -0,0 +1,37 @@
+libmakepkg_module = 'lint_pkgbuild'
+
+sources = [
+ 'arch.sh.in',
+ 'backup.sh.in',
+ 'changelog.sh.in',
+ 'checkdepends.sh.in',
+ 'conflicts.sh.in',
+ 'depends.sh.in',
+ 'epoch.sh.in',
+ 'install.sh.in',
+ 'makedepends.sh.in',
+ 'optdepends.sh.in',
+ 'options.sh.in',
+ 'package_function.sh.in',
+ 'pkgbase.sh.in',
+ 'pkglist.sh.in',
+ 'pkgname.sh.in',
+ 'pkgrel.sh.in',
+ 'pkgver.sh.in',
+ 'provides.sh.in',
+ 'source.sh.in',
+ 'util.sh.in',
+ 'variable.sh.in',
+]
+
+foreach src : sources
+ output_dir = join_paths(get_option('datadir'), 'makepkg', libmakepkg_module)
+
+ custom_target(
+ libmakepkg_module + '_' + src.underscorify(),
+ command : [ SCRIPT_EDITOR, '@INPUT@', '@OUTPUT@' ],
+ input : src,
+ output : '@BASENAME@',
+ install : true,
+ install_dir : output_dir)
+endforeach
diff --git a/scripts/libmakepkg/meson.build b/scripts/libmakepkg/meson.build
new file mode 100644
index 00000000..07475b4d
--- /dev/null
+++ b/scripts/libmakepkg/meson.build
@@ -0,0 +1,31 @@
+libmakepkg_modules = [
+ { 'name' : 'integrity', 'has_subdir' : true },
+ { 'name' : 'lint_config', 'has_subdir' : true },
+ { 'name' : 'lint_package', 'has_subdir' : true },
+ { 'name' : 'lint_pkgbuild', 'has_subdir' : true },
+ { 'name' : 'source', 'has_subdir' : true },
+ { 'name' : 'srcinfo', },
+ { 'name' : 'tidy', 'has_subdir' : true },
+ { 'name' : 'util', 'has_subdir' : true },
+]
+
+mkdir_p = 'mkdir -p $DESTDIR/@0@'
+
+foreach module : libmakepkg_modules
+ custom_target(
+ 'libmakepkg_@0@'.format(module['name']),
+ command : [ SCRIPT_EDITOR, '@INPUT@', '@OUTPUT@' ],
+ input : '@0@.sh.in'.format(module['name']),
+ output : '@BASENAME@',
+ install : true,
+ install_dir : join_paths(get_option('datadir'), 'makepkg'))
+
+ if module.get('has_subdir', false)
+ subdir(module['name'])
+ path = join_paths(get_option('prefix'),
+ get_option('datadir'),
+ 'makepkg',
+ module['name'])
+ meson.add_install_script('sh', '-c', mkdir_p.format(path))
+ endif
+endforeach
diff --git a/scripts/libmakepkg/source/meson.build b/scripts/libmakepkg/source/meson.build
new file mode 100644
index 00000000..59326133
--- /dev/null
+++ b/scripts/libmakepkg/source/meson.build
@@ -0,0 +1,22 @@
+libmakepkg_module = 'source'
+
+sources = [
+ 'bzr.sh.in',
+ 'file.sh.in',
+ 'git.sh.in',
+ 'hg.sh.in',
+ 'local.sh.in',
+ 'svn.sh.in',
+]
+
+foreach src : sources
+ output_dir = join_paths(get_option('datadir'), 'makepkg', libmakepkg_module)
+
+ custom_target(
+ libmakepkg_module + '_' + src.underscorify(),
+ command : [ SCRIPT_EDITOR, '@INPUT@', '@OUTPUT@' ],
+ input : src,
+ output : '@BASENAME@',
+ install : true,
+ install_dir : output_dir)
+endforeach
diff --git a/scripts/libmakepkg/tidy/meson.build b/scripts/libmakepkg/tidy/meson.build
new file mode 100644
index 00000000..052ac7a2
--- /dev/null
+++ b/scripts/libmakepkg/tidy/meson.build
@@ -0,0 +1,23 @@
+libmakepkg_module = 'tidy'
+
+sources = [
+ 'docs.sh.in',
+ 'emptydirs.sh.in',
+ 'libtool.sh.in',
+ 'purge.sh.in',
+ 'staticlibs.sh.in',
+ 'strip.sh.in',
+ 'zipman.sh.in',
+]
+
+foreach src : sources
+ output_dir = join_paths(get_option('datadir'), 'makepkg', libmakepkg_module)
+
+ custom_target(
+ libmakepkg_module + '_' + src.underscorify(),
+ command : [ SCRIPT_EDITOR, '@INPUT@', '@OUTPUT@' ],
+ input : src,
+ output : '@BASENAME@',
+ install : true,
+ install_dir : output_dir)
+endforeach
diff --git a/scripts/libmakepkg/util/meson.build b/scripts/libmakepkg/util/meson.build
new file mode 100644
index 00000000..b0e829c4
--- /dev/null
+++ b/scripts/libmakepkg/util/meson.build
@@ -0,0 +1,24 @@
+libmakepkg_module = 'util'
+
+sources = [
+ 'compress.sh.in',
+ 'error.sh.in',
+ 'message.sh.in',
+ 'option.sh.in',
+ 'parseopts.sh.in',
+ 'pkgbuild.sh.in',
+ 'source.sh.in',
+ 'util.sh.in',
+]
+
+foreach src : sources
+ output_dir = join_paths(get_option('datadir'), 'makepkg', libmakepkg_module)
+
+ custom_target(
+ libmakepkg_module + '_' + src.underscorify(),
+ command : [ SCRIPT_EDITOR, '@INPUT@', '@OUTPUT@' ],
+ input : src,
+ output : '@BASENAME@',
+ install : true,
+ install_dir : output_dir)
+endforeach
diff --git a/scripts/meson.build b/scripts/meson.build
new file mode 100644
index 00000000..1fe3fb78
--- /dev/null
+++ b/scripts/meson.build
@@ -0,0 +1,66 @@
+scripts = [
+ 'makepkg-template.pl.in',
+ 'makepkg.sh.in',
+ 'pacman-db-upgrade.sh.in',
+ 'pacman-key.sh.in',
+ 'pkgdelta.sh.in',
+ 'repo-add.sh.in'
+]
+
+library_files = [
+ 'library/human_to_size.sh',
+ 'library/size_to_human.sh',
+]
+
+SCRIPT_EDITOR = find_program(configure_file(
+ input : join_paths(meson.source_root(), 'build-aux/edit-script.sh.in'),
+ output : 'edit-script.sh',
+ configuration : substs))
+
+m4_edit = generator(
+ M4,
+ arguments : ['-P', '-I', meson.current_source_dir(), '@INPUT@'],
+ output : '@PLAINNAME@',
+ capture : true)
+
+foreach script : scripts
+ custom_target(
+ script,
+ input : m4_edit.process(script),
+ command : [ SCRIPT_EDITOR, '@INPUT@', '@OUTPUT@', '0755'],
+ output : script.split('.')[0],
+ depend_files : library_files,
+ install : true,
+ install_dir : get_option('bindir'))
+endforeach
+
+foreach symlink : ['repo-remove', 'repo-elephant']
+ meson.add_install_script(MESON_MAKE_SYMLINK,
+ 'repo-add',
+ join_paths(BINDIR, symlink))
+endforeach
+
+subdir('libmakepkg')
+
+custom_target(
+ 'bash_completion',
+ command : [ SCRIPT_EDITOR, '@INPUT@', '@OUTPUT@' ],
+ input : 'completion/bash_completion.in',
+ output : 'pacman',
+ install : true,
+ install_dir : BASHCOMPDIR)
+
+foreach symlink : ['pacman-key', 'makepkg']
+ meson.add_install_script(MESON_MAKE_SYMLINK,
+ 'pacman',
+ join_paths(BASHCOMPDIR, symlink))
+endforeach
+
+zsh_completion_dir = join_paths(DATAROOTDIR, 'zsh/site-functions')
+custom_target(
+ 'zsh_completion',
+ command : [ SCRIPT_EDITOR, '@INPUT@', '@OUTPUT@' ],
+ input : 'completion/zsh_completion.in',
+ output : '_pacman',
+ install : true,
+ install_dir : zsh_completion_dir)
diff --git a/scripts/po/meson.build b/scripts/po/meson.build
new file mode 100644
index 00000000..d8b8c51c
--- /dev/null
+++ b/scripts/po/meson.build
@@ -0,0 +1,15 @@
+i18n.gettext(
+ 'pacman-scripts',
+ args : [
+ '--directory=@0@'.format(meson.current_source_dir()),
+ '--msgid-bugs-address=http://bugs.archlinux.org/index.php?project=3',
+ '--copyright-holder="Pacman Development Team <pacman-dev(a)archlinux.org>"',
+ '--language', 'shell',
+
+ '--keyword=_',
+ '--flag=_:1:c-format',
+
+ '--keyword=_n:1,2',
+ '--flag=_n:1:c-format',
+ '--flag=_n:2:c-format',
+ ])
diff --git a/src/common/meson.build b/src/common/meson.build
new file mode 100644
index 00000000..1443be3b
--- /dev/null
+++ b/src/common/meson.build
@@ -0,0 +1,4 @@
+libcommon_sources = files('''
+ ini.c ini.h
+ util-common.c util-common.h
+'''.split())
diff --git a/src/pacman/meson.build b/src/pacman/meson.build
new file mode 100644
index 00000000..6926f676
--- /dev/null
+++ b/src/pacman/meson.build
@@ -0,0 +1,23 @@
+pacman_sources = files('''
+ check.h check.c
+ conf.h conf.c
+ database.c
+ deptest.c
+ files.c
+ package.h package.c
+ pacman.h pacman.c
+ query.c
+ remove.c
+ sighandler.h sighandler.c
+ sync.c
+ callback.h callback.c
+ upgrade.c
+ util.h util.c
+'''.split())
+
+pacman_conf_sources = files('''
+ pacman-conf.c
+ util.h util.c
+ callback.h callback.c
+ conf.h conf.c
+'''.split())
diff --git a/src/pacman/po/meson.build b/src/pacman/po/meson.build
new file mode 100644
index 00000000..eb45fa1c
--- /dev/null
+++ b/src/pacman/po/meson.build
@@ -0,0 +1,15 @@
+i18n.gettext(
+ 'pacman',
+ args : [
+ '--directory=@0@'.format(meson.current_source_dir()),
+ '--msgid-bugs-address=http://bugs.archlinux.org/index.php?project=3',
+ '--copyright-holder="Pacman Development Team <pacman-dev(a)archlinux.org>"',
+ '--language', 'c',
+
+ '--keyword=_',
+ '--flag=_:1:c-format',
+
+ '--keyword=_n:1,2',
+ '--flag=_n:1:c-format',
+ '--flag=_n:2:c-format',
+ ])
diff --git a/src/util/meson.build b/src/util/meson.build
new file mode 100644
index 00000000..cc219670
--- /dev/null
+++ b/src/util/meson.build
@@ -0,0 +1,3 @@
+cleanupdelta_sources = files('cleanupdelta.c')
+testpkg_sources = files('testpkg.c')
+vercmp_sources = files('vercmp.c')
diff --git a/test/pacman/meson.build b/test/pacman/meson.build
new file mode 100644
index 00000000..dbdb429e
--- /dev/null
+++ b/test/pacman/meson.build
@@ -0,0 +1,357 @@
+pacman_tests = [
+ { 'name': 'tests/backup001.py' },
+ { 'name': 'tests/clean001.py' },
+ { 'name': 'tests/clean002.py' },
+ { 'name': 'tests/clean003.py' },
+ { 'name': 'tests/clean004.py' },
+ { 'name': 'tests/clean005.py' },
+ { 'name': 'tests/config001.py' },
+ { 'name': 'tests/config002.py' },
+ { 'name': 'tests/database001.py' },
+ { 'name': 'tests/database002.py' },
+ { 'name': 'tests/database010.py' },
+ { 'name': 'tests/database011.py' },
+ { 'name': 'tests/database012.py' },
+ { 'name': 'tests/dbonly-extracted-files.py' },
+ { 'name': 'tests/depconflict100.py' },
+ { 'name': 'tests/depconflict110.py' },
+ { 'name': 'tests/depconflict111.py' },
+ { 'name': 'tests/depconflict120.py' },
+ { 'name': 'tests/dependency-cycle-fixed-by-upgrade.py' },
+ { 'name': 'tests/deprange001.py',
+ 'should_fail': true },
+ { 'name': 'tests/deptest001.py' },
+ { 'name': 'tests/dummy001.py' },
+ { 'name': 'tests/epoch001.py' },
+ { 'name': 'tests/epoch002.py' },
+ { 'name': 'tests/epoch003.py' },
+ { 'name': 'tests/epoch004.py' },
+ { 'name': 'tests/epoch005.py' },
+ { 'name': 'tests/epoch010.py' },
+ { 'name': 'tests/epoch011.py' },
+ { 'name': 'tests/epoch012.py' },
+ { 'name': 'tests/file-conflict-with-installed-pkg.py' },
+ { 'name': 'tests/fileconflict001.py' },
+ { 'name': 'tests/fileconflict002.py' },
+ { 'name': 'tests/fileconflict003.py' },
+ { 'name': 'tests/fileconflict004.py' },
+ { 'name': 'tests/fileconflict005.py' },
+ { 'name': 'tests/fileconflict006.py' },
+ { 'name': 'tests/fileconflict007.py' },
+ { 'name': 'tests/fileconflict008.py' },
+ { 'name': 'tests/fileconflict009.py' },
+ { 'name': 'tests/fileconflict010.py' },
+ { 'name': 'tests/fileconflict011.py' },
+ { 'name': 'tests/fileconflict012.py' },
+ { 'name': 'tests/fileconflict013.py' },
+ { 'name': 'tests/fileconflict015.py' },
+ { 'name': 'tests/fileconflict016.py' },
+ { 'name': 'tests/fileconflict017.py' },
+ { 'name': 'tests/fileconflict020.py' },
+ { 'name': 'tests/fileconflict021.py' },
+ { 'name': 'tests/fileconflict022.py' },
+ { 'name': 'tests/fileconflict023.py' },
+ { 'name': 'tests/fileconflict024.py' },
+ { 'name': 'tests/fileconflict025.py' },
+ { 'name': 'tests/fileconflict030.py' },
+ { 'name': 'tests/fileconflict031.py' },
+ { 'name': 'tests/fileconflict032.py' },
+ { 'name': 'tests/hook-abortonfail.py' },
+ { 'name': 'tests/hook-description-reused.py' },
+ { 'name': 'tests/hook-exec-reused.py' },
+ { 'name': 'tests/hook-exec-with-arguments.py' },
+ { 'name': 'tests/hook-file-change-packages.py' },
+ { 'name': 'tests/hook-file-remove-trigger-match.py' },
+ { 'name': 'tests/hook-file-upgrade-nomatch.py' },
+ { 'name': 'tests/hook-invalid-trigger.py' },
+ { 'name': 'tests/hook-pkg-install-trigger-match.py' },
+ { 'name': 'tests/hook-pkg-postinstall-trigger-match.py' },
+ { 'name': 'tests/hook-pkg-remove-trigger-match.py' },
+ { 'name': 'tests/hook-pkg-upgrade-trigger-match.py' },
+ { 'name': 'tests/hook-target-list.py' },
+ { 'name': 'tests/hook-type-reused.py' },
+ { 'name': 'tests/hook-upgrade-trigger-no-match.py' },
+ { 'name': 'tests/hook-when-reused.py' },
+ { 'name': 'tests/ignore001.py' },
+ { 'name': 'tests/ignore002.py' },
+ { 'name': 'tests/ignore003.py' },
+ { 'name': 'tests/ignore004.py' },
+ { 'name': 'tests/ignore005.py' },
+ { 'name': 'tests/ignore006.py' },
+ { 'name': 'tests/ignore007.py' },
+ { 'name': 'tests/ignore008.py' },
+ { 'name': 'tests/ldconfig001.py' },
+ { 'name': 'tests/ldconfig002.py' },
+ { 'name': 'tests/ldconfig003.py' },
+ { 'name': 'tests/mode001.py' },
+ { 'name': 'tests/mode002.py' },
+ { 'name': 'tests/mode003.py' },
+ { 'name': 'tests/noupgrade-inverted.py' },
+ { 'name': 'tests/overwrite-files-match-negated.py' },
+ { 'name': 'tests/overwrite-files-match.py' },
+ { 'name': 'tests/overwrite-files-nonmatch.py' },
+ { 'name': 'tests/pacman001.py' },
+ { 'name': 'tests/pacman002.py' },
+ { 'name': 'tests/pacman003.py' },
+ { 'name': 'tests/pacman004.py' },
+ { 'name': 'tests/pacman005.py' },
+ { 'name': 'tests/provision001.py' },
+ { 'name': 'tests/provision002.py' },
+ { 'name': 'tests/provision003.py' },
+ { 'name': 'tests/provision004.py' },
+ { 'name': 'tests/provision010.py' },
+ { 'name': 'tests/provision011.py' },
+ { 'name': 'tests/provision012.py' },
+ { 'name': 'tests/provision020.py' },
+ { 'name': 'tests/provision021.py' },
+ { 'name': 'tests/provision022.py' },
+ { 'name': 'tests/query001.py' },
+ { 'name': 'tests/query002.py' },
+ { 'name': 'tests/query003.py' },
+ { 'name': 'tests/query004.py' },
+ { 'name': 'tests/query005.py' },
+ { 'name': 'tests/query006.py',
+ # expect failure on 32 bit machines
+ 'should_fail': cc.sizeof('ssize_t') < 8 },
+ { 'name': 'tests/query007.py' },
+ { 'name': 'tests/query010.py' },
+ { 'name': 'tests/query011.py' },
+ { 'name': 'tests/query012.py' },
+ { 'name': 'tests/querycheck001.py' },
+ { 'name': 'tests/querycheck002.py' },
+ { 'name': 'tests/querycheck_fast_file_type.py' },
+ { 'name': 'tests/reason001.py' },
+ { 'name': 'tests/remove-assumeinstalled.py' },
+ { 'name': 'tests/remove-directory-replaced-with-symlink.py' },
+ { 'name': 'tests/remove-optdepend-of-installed-package.py' },
+ { 'name': 'tests/remove-recursive-cycle.py' },
+ { 'name': 'tests/remove001.py' },
+ { 'name': 'tests/remove002.py' },
+ { 'name': 'tests/remove010.py' },
+ { 'name': 'tests/remove011.py' },
+ { 'name': 'tests/remove012.py' },
+ { 'name': 'tests/remove020.py' },
+ { 'name': 'tests/remove021.py' },
+ { 'name': 'tests/remove030.py' },
+ { 'name': 'tests/remove031.py' },
+ { 'name': 'tests/remove040.py' },
+ { 'name': 'tests/remove041.py' },
+ { 'name': 'tests/remove042.py' },
+ { 'name': 'tests/remove043.py' },
+ { 'name': 'tests/remove044.py' },
+ { 'name': 'tests/remove045.py' },
+ { 'name': 'tests/remove047.py' },
+ { 'name': 'tests/remove049.py' },
+ { 'name': 'tests/remove050.py' },
+ { 'name': 'tests/remove051.py' },
+ { 'name': 'tests/remove052.py' },
+ { 'name': 'tests/remove060.py' },
+ { 'name': 'tests/remove070.py' },
+ { 'name': 'tests/remove071.py' },
+ { 'name': 'tests/replace100.py' },
+ { 'name': 'tests/replace101.py' },
+ { 'name': 'tests/replace102.py' },
+ { 'name': 'tests/replace103.py' },
+ { 'name': 'tests/replace104.py' },
+ { 'name': 'tests/replace110.py',
+ 'should_fail': true },
+ { 'name': 'tests/scriptlet001.py' },
+ { 'name': 'tests/scriptlet002.py' },
+ { 'name': 'tests/sign001.py' },
+ { 'name': 'tests/sign002.py' },
+ { 'name': 'tests/skip-remove-with-glob-chars.py' },
+ { 'name': 'tests/smoke001.py' },
+ { 'name': 'tests/smoke002.py' },
+ { 'name': 'tests/smoke003.py' },
+ { 'name': 'tests/smoke004.py' },
+ { 'name': 'tests/symlink-replace-with-dir.py' },
+ { 'name': 'tests/symlink001.py' },
+ { 'name': 'tests/symlink002.py' },
+ { 'name': 'tests/symlink010.py' },
+ { 'name': 'tests/symlink011.py' },
+ { 'name': 'tests/symlink012.py' },
+ { 'name': 'tests/symlink020.py' },
+ { 'name': 'tests/symlink021.py' },
+ { 'name': 'tests/sync-install-assumeinstalled.py' },
+ { 'name': 'tests/sync-nodepversion01.py' },
+ { 'name': 'tests/sync-nodepversion02.py' },
+ { 'name': 'tests/sync-nodepversion03.py' },
+ { 'name': 'tests/sync-nodepversion04.py' },
+ { 'name': 'tests/sync-nodepversion05.py' },
+ { 'name': 'tests/sync-nodepversion06.py' },
+ { 'name': 'tests/sync-sysupgrade-print-replaced-packages.py' },
+ { 'name': 'tests/sync-update-assumeinstalled.py' },
+ { 'name': 'tests/sync-update-package-removing-required-provides.py',
+ 'should_fail': true },
+ { 'name': 'tests/sync001.py' },
+ { 'name': 'tests/sync002.py' },
+ { 'name': 'tests/sync003.py' },
+ { 'name': 'tests/sync009.py' },
+ { 'name': 'tests/sync010.py' },
+ { 'name': 'tests/sync011.py' },
+ { 'name': 'tests/sync012.py' },
+ { 'name': 'tests/sync020.py' },
+ { 'name': 'tests/sync021.py' },
+ { 'name': 'tests/sync022.py' },
+ { 'name': 'tests/sync023.py' },
+ { 'name': 'tests/sync024.py' },
+ { 'name': 'tests/sync030.py' },
+ { 'name': 'tests/sync031.py' },
+ { 'name': 'tests/sync040.py' },
+ { 'name': 'tests/sync041.py' },
+ { 'name': 'tests/sync042.py' },
+ { 'name': 'tests/sync043.py' },
+ { 'name': 'tests/sync044.py' },
+ { 'name': 'tests/sync045.py' },
+ { 'name': 'tests/sync046.py' },
+ { 'name': 'tests/sync050.py' },
+ { 'name': 'tests/sync051.py' },
+ { 'name': 'tests/sync052.py' },
+ { 'name': 'tests/sync100.py' },
+ { 'name': 'tests/sync1000.py' },
+ { 'name': 'tests/sync1003.py' },
+ { 'name': 'tests/sync1004.py' },
+ { 'name': 'tests/sync1008.py' },
+ { 'name': 'tests/sync101.py' },
+ { 'name': 'tests/sync102.py' },
+ { 'name': 'tests/sync103.py' },
+ { 'name': 'tests/sync104.py' },
+ { 'name': 'tests/sync110.py' },
+ { 'name': 'tests/sync1100.py' },
+ { 'name': 'tests/sync1101.py' },
+ { 'name': 'tests/sync1102.py' },
+ { 'name': 'tests/sync1103.py' },
+ { 'name': 'tests/sync1104.py' },
+ { 'name': 'tests/sync1105.py' },
+ { 'name': 'tests/sync120.py' },
+ { 'name': 'tests/sync130.py' },
+ { 'name': 'tests/sync131.py' },
+ { 'name': 'tests/sync132.py' },
+ { 'name': 'tests/sync133.py' },
+ { 'name': 'tests/sync134.py' },
+ { 'name': 'tests/sync135.py' },
+ { 'name': 'tests/sync136.py' },
+ { 'name': 'tests/sync137.py' },
+ { 'name': 'tests/sync138.py' },
+ { 'name': 'tests/sync139.py' },
+ { 'name': 'tests/sync140.py' },
+ { 'name': 'tests/sync141.py' },
+ { 'name': 'tests/sync150.py' },
+ { 'name': 'tests/sync200.py' },
+ { 'name': 'tests/sync300.py' },
+ { 'name': 'tests/sync306.py' },
+ { 'name': 'tests/sync400.py' },
+ { 'name': 'tests/sync401.py' },
+ { 'name': 'tests/sync402.py' },
+ { 'name': 'tests/sync403.py',
+ 'should_fail': true },
+ { 'name': 'tests/sync404.py' },
+ { 'name': 'tests/sync405.py' },
+ { 'name': 'tests/sync406.py',
+ 'should_fail': true },
+ { 'name': 'tests/sync407.py' },
+ { 'name': 'tests/sync500.py' },
+ { 'name': 'tests/sync501.py' },
+ { 'name': 'tests/sync502.py' },
+ { 'name': 'tests/sync503.py' },
+ { 'name': 'tests/sync600.py' },
+ { 'name': 'tests/sync700.py' },
+ { 'name': 'tests/sync701.py' },
+ { 'name': 'tests/sync702.py' },
+ { 'name': 'tests/sync890.py' },
+ { 'name': 'tests/sync891.py' },
+ { 'name': 'tests/sync892.py' },
+ { 'name': 'tests/sync893.py' },
+ { 'name': 'tests/sync895.py' },
+ { 'name': 'tests/sync896.py' },
+ { 'name': 'tests/sync897.py' },
+ { 'name': 'tests/sync898.py' },
+ { 'name': 'tests/sync899.py' },
+ { 'name': 'tests/sync900.py' },
+ { 'name': 'tests/sync901.py' },
+ { 'name': 'tests/sync990.py' },
+ { 'name': 'tests/sync992.py' },
+ { 'name': 'tests/sync993.py' },
+ { 'name': 'tests/sync999.py' },
+ { 'name': 'tests/trans001.py' },
+ { 'name': 'tests/type001.py' },
+ { 'name': 'tests/unresolvable001.py' },
+ { 'name': 'tests/upgrade001.py' },
+ { 'name': 'tests/upgrade002.py' },
+ { 'name': 'tests/upgrade003.py' },
+ { 'name': 'tests/upgrade004.py' },
+ { 'name': 'tests/upgrade005.py' },
+ { 'name': 'tests/upgrade006.py' },
+ { 'name': 'tests/upgrade010.py' },
+ { 'name': 'tests/upgrade011.py' },
+ { 'name': 'tests/upgrade013.py' },
+ { 'name': 'tests/upgrade020.py' },
+ { 'name': 'tests/upgrade021.py' },
+ { 'name': 'tests/upgrade022.py' },
+ { 'name': 'tests/upgrade023.py' },
+ { 'name': 'tests/upgrade024.py' },
+ { 'name': 'tests/upgrade025.py' },
+ { 'name': 'tests/upgrade026.py' },
+ { 'name': 'tests/upgrade027.py' },
+ { 'name': 'tests/upgrade028.py' },
+ { 'name': 'tests/upgrade029.py' },
+ { 'name': 'tests/upgrade030.py' },
+ { 'name': 'tests/upgrade031.py' },
+ { 'name': 'tests/upgrade032.py' },
+ { 'name': 'tests/upgrade040.py' },
+ { 'name': 'tests/upgrade041.py' },
+ { 'name': 'tests/upgrade042.py' },
+ { 'name': 'tests/upgrade043.py' },
+ { 'name': 'tests/upgrade045.py' },
+ { 'name': 'tests/upgrade050.py' },
+ { 'name': 'tests/upgrade051.py' },
+ { 'name': 'tests/upgrade052.py' },
+ { 'name': 'tests/upgrade053.py' },
+ { 'name': 'tests/upgrade054.py' },
+ { 'name': 'tests/upgrade055.py' },
+ { 'name': 'tests/upgrade056.py' },
+ { 'name': 'tests/upgrade057.py' },
+ { 'name': 'tests/upgrade058.py' },
+ { 'name': 'tests/upgrade059.py' },
+ { 'name': 'tests/upgrade060.py' },
+ { 'name': 'tests/upgrade061.py' },
+ { 'name': 'tests/upgrade070.py' },
+ { 'name': 'tests/upgrade071.py' },
+ { 'name': 'tests/upgrade072.py' },
+ { 'name': 'tests/upgrade073.py' },
+ { 'name': 'tests/upgrade074.py' },
+ { 'name': 'tests/upgrade075.py' },
+ { 'name': 'tests/upgrade076.py' },
+ { 'name': 'tests/upgrade077.py' },
+ { 'name': 'tests/upgrade078.py',
+ 'should_fail': true },
+ { 'name': 'tests/upgrade080.py' },
+ { 'name': 'tests/upgrade081.py' },
+ { 'name': 'tests/upgrade082.py' },
+ { 'name': 'tests/upgrade083.py' },
+ { 'name': 'tests/upgrade084.py' },
+ { 'name': 'tests/upgrade090.py' },
+ { 'name': 'tests/upgrade100.py' },
+ { 'name': 'tests/xfercommand001.py' },
+]
+
+foreach testobj : pacman_tests
+ input = testobj.get('name')
+ test_name = input.split('/')[1]
+ should_fail = testobj.get('should_fail', false)
+
+ test(
+ test_name,
+ PYTHON,
+ args : [
+ join_paths(meson.source_root(), 'build-aux/tap-driver.py'),
+ join_paths(meson.current_source_dir(), 'pactest.py'),
+ '--scriptlet-shell', get_option('scriptlet-shell'),
+ '--bindir', meson.build_root(),
+ '--ldconfig', LDCONFIG,
+ '--verbose',
+ join_paths(meson.current_source_dir(), input)
+ ],
+ depends : [pacman_bin],
+ should_fail : should_fail)
+endforeach
diff --git a/test/scripts/meson.build b/test/scripts/meson.build
new file mode 100644
index 00000000..6d6194dd
--- /dev/null
+++ b/test/scripts/meson.build
@@ -0,0 +1,12 @@
+tests = [
+ 'parseopts_test.sh',
+ 'makepkg-template_test.sh',
+ 'human_to_size_test.sh',
+]
+
+foreach tst : tests
+ test(tst,
+ BASH,
+ env : TEST_ENV,
+ args : [join_paths(meson.current_source_dir(), tst)])
+endforeach
diff --git a/test/util/meson.build b/test/util/meson.build
new file mode 100644
index 00000000..07b29e5c
--- /dev/null
+++ b/test/util/meson.build
@@ -0,0 +1,6 @@
+test('vercmptest',
+ BASH,
+ env : TEST_ENV,
+ args : [
+ join_paths(meson.current_source_dir(), 'vercmptest.sh')
+ ])
--
2.19.1
5
17
[pacman-dev] [PATCH 1/2] makepkg: fix .PKGINFO/.BUILDINFO files swallowing status printing
by Eli Schwartz 31 Oct '18
by Eli Schwartz 31 Oct '18
31 Oct '18
The respective write_* functions are low-level and shouldn't be
outputting statuses; move these to the logic flow where they are used.
This ensures the functions can be used in the future wherever, and also
solves an issue where, as fallout from the message.sh retrofitting in
commit 882e707e40bbade0111cf3bdedbdac4d4b70453b, the statuses got
redirected to the actual files.
The resulting package was technically correct, except that it contained
useless lines which pacman ignored, and repo-add also ignored but at the
same time generated an error message:
/usr/bin/repo-add: line 335: declare: `=-> Generating .PKGINFO file...': not a valid identifier
Thirdparty package tools with stricter parsers may abort with errors,
and "repose" is known to do so.
Signed-off-by: Eli Schwartz <eschwartz(a)archlinux.org>
---
scripts/makepkg.sh.in | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/scripts/makepkg.sh.in b/scripts/makepkg.sh.in
index 87253883..3ac03d11 100644
--- a/scripts/makepkg.sh.in
+++ b/scripts/makepkg.sh.in
@@ -634,7 +634,6 @@ write_pkginfo() {
merge_arch_attrs
- msg2 "$(gettext "Generating %s file...")" ".PKGINFO"
printf "# Generated by makepkg %s\n" "$makepkg_version"
printf "# using %s\n" "$(fakeroot -v)"
@@ -672,8 +671,6 @@ write_pkginfo() {
}
write_buildinfo() {
- msg2 "$(gettext "Generating %s file...")" ".BUILDINFO"
-
write_kv_pair "format" "1"
write_kv_pair "pkgname" "$pkgname"
@@ -728,7 +725,9 @@ create_package() {
msg "$(gettext "Creating package \"%s\"...")" "$pkgname"
pkgarch=$(get_pkg_arch)
+ msg2 "$(gettext "Generating %s file...")" ".PKGINFO"
write_pkginfo > .PKGINFO
+ msg2 "$(gettext "Generating %s file...")" ".BUILDINFO"
write_buildinfo > .BUILDINFO
# check for changelog/install files
--
2.19.1
1
1
[pacman-dev] [PATCH] meson: add a wrapper to bootstrap scripts from within build dir
by Dave Reisner 29 Oct '18
by Dave Reisner 29 Oct '18
29 Oct '18
This doesn't do quite as good of a job of "hiding away" the real script
as we did with autotools, but it satisfies the need for being able to
run scripts which depend on libmakepkg with the local copy within the
repo. We do, however, improve upon the autotools script by ensuring that
the bash path used in configuring pacman is the interpreter used to run
the underlying script.
---
Naturally, this applies on top of my previous meson patch.
build-aux/meson-install-script.sh | 6 ++++++
build-aux/script-wrapper.sh.in | 6 ++++++
meson.build | 1 +
scripts/meson.build | 33 +++++++++++++++++++++++++++----
4 files changed, 42 insertions(+), 4 deletions(-)
create mode 100644 build-aux/meson-install-script.sh
create mode 100755 build-aux/script-wrapper.sh.in
diff --git a/build-aux/meson-install-script.sh b/build-aux/meson-install-script.sh
new file mode 100644
index 00000000..f5a42fca
--- /dev/null
+++ b/build-aux/meson-install-script.sh
@@ -0,0 +1,6 @@
+#!/bin/sh
+
+built_script=$1
+dest_path=$2
+
+install -Dm755 "$built_script" "$DESTDIR/$dest_path"
diff --git a/build-aux/script-wrapper.sh.in b/build-aux/script-wrapper.sh.in
new file mode 100755
index 00000000..f87ae6f0
--- /dev/null
+++ b/build-aux/script-wrapper.sh.in
@@ -0,0 +1,6 @@
+#!/bin/bash
+
+# This script serves as a trampoline for running scripts which depend on
+# libmakepkg with the libmakepkg within the build tree.
+
+LIBRARY=@BUILDDIR@/libmakepkg exec @BASH@ -$- @REAL_PROGPATH@ "$@"
diff --git a/meson.build b/meson.build
index d81c86b7..1ec63a56 100644
--- a/meson.build
+++ b/meson.build
@@ -33,6 +33,7 @@ SED = find_program('sed')
DU = find_program('du')
LDCONFIG = get_option('ldconfig')
MESON_MAKE_SYMLINK = join_paths(meson.source_root(), 'build-aux/meson-make-symlink.sh')
+MESON_INSTALL_SCRIPT = join_paths(meson.source_root(), 'build-aux/meson-install-script.sh')
BASH = find_program('bash4', 'bash')
if BASH.found()
diff --git a/scripts/meson.build b/scripts/meson.build
index 1fe3fb78..535eccba 100644
--- a/scripts/meson.build
+++ b/scripts/meson.build
@@ -24,14 +24,39 @@ m4_edit = generator(
capture : true)
foreach script : scripts
- custom_target(
+ script_shortname = script.split('.')[0]
+
+ # Build the script, but don't install it. We want to keep it as a "private"
+ # artifact that we reference from a wrapper script in order to bootstrap it
+ # the build directory.
+ internal_script = custom_target(
script,
input : m4_edit.process(script),
command : [ SCRIPT_EDITOR, '@INPUT@', '@OUTPUT@', '0755'],
- output : script.split('.')[0],
+ output : script,
depend_files : library_files,
- install : true,
- install_dir : get_option('bindir'))
+ build_by_default : true)
+
+ # Create a wrapper script that bootstraps the real script within the build
+ # directory.
+ custom_target(
+ 'wrap_@0@'.format(script_shortname),
+ input : join_paths(meson.source_root(), 'build-aux', 'script-wrapper.sh.in'),
+ output : script_shortname,
+ build_by_default : true,
+ command : [
+ SED,
+ '-e', 's,@BASH@,"@0@",'.format(BASH.path()),
+ '-e', 's,@BUILDDIR@,"@0@",'.format(meson.current_build_dir()),
+ '-e', 's,@REAL_PROGPATH@,"@0@",'.format(internal_script.full_path()),
+ '@INPUT@',
+ ],
+ capture : true)
+
+ # Install the real script
+ meson.add_install_script(MESON_INSTALL_SCRIPT,
+ internal_script.full_path(),
+ join_paths(BINDIR, script_shortname))
endforeach
foreach symlink : ['repo-remove', 'repo-elephant']
--
2.19.1
1
0
[pacman-dev] [PATCH] pacman-key: just accept one file to verify, and enforce detached sigs
by Eli Schwartz 21 Oct '18
by Eli Schwartz 21 Oct '18
21 Oct '18
Simply pass options on to gpg the same way gpg uses them -- no looping
through and checking lots of signatures.
This prevents a situation where the signature file to be verified is
manipulated to contain a complete signature which is valid, but not a
detached signature for the file you are actually trying to verify.
gpg does not offer an option to verify many files at once by naming each
signature/file pair, and there's no reason for us to do so either, since
it would be quite tiresome to do so.
Signed-off-by: Eli Schwartz <eschwartz(a)archlinux.org>
---
scripts/pacman-key.sh.in | 25 +++++++++++++------------
1 file changed, 13 insertions(+), 12 deletions(-)
diff --git a/scripts/pacman-key.sh.in b/scripts/pacman-key.sh.in
index 0f1630a9..0573e92f 100644
--- a/scripts/pacman-key.sh.in
+++ b/scripts/pacman-key.sh.in
@@ -486,18 +486,19 @@ refresh_keys() {
}
verify_sig() {
- local ret=0
- for sig; do
- msg "Checking %s..." "$sig"
- if grep -q 'BEGIN PGP SIGNATURE' "$sig"; then
- error "$(gettext "Cannot use armored signatures for packages: %s")" "$sig"
- return 1
- fi
- if ! "${GPG_PACMAN[@]}" --status-fd 1 --verify "$sig" | grep -qE '^\[GNUPG:\] TRUST_(FULLY|ULTIMATE).*$'; then
- error "$(gettext "The signature identified by %s could not be verified.")" "$sig"
- ret=1
- fi
- done
+ local ret=0 sig=$1 file=$2
+ if [[ -z $file ]]; then
+ file=${sig%.*}
+ fi
+ msg "Checking %s..." "$sig"
+ if grep -q 'BEGIN PGP SIGNATURE' "$sig"; then
+ error "$(gettext "Cannot use armored signatures for packages: %s")" "$sig"
+ exit 1
+ fi
+ if ! "${GPG_PACMAN[@]}" --status-fd 1 --verify "$sig" "$file" | grep -qE '^\[GNUPG:\] TRUST_(FULLY|ULTIMATE).*$'; then
+ error "$(gettext "The signature identified by %s could not be verified.")" "$sig"
+ ret=1
+ fi
exit $ret
}
--
2.17.0
2
3
21 Oct '18
[[ ${array[@]} ]] will resolve to false if array only contains empty
strings. This means that values such as "depends=('')" can be inserted
into a pkgbuild and bypass the linting.
This causes makepkg to successfully build the package while pacman
refuses to install it because of the unmet dependency on ''.
Instead check the length of the array.
Signed-off-by: morganamilo <morganamilo(a)gmail.com>
diff --git a/scripts/libmakepkg/util/pkgbuild.sh.in b/scripts/libmakepkg/util/pkgbuild.sh.in
index c6f8a82d..b29229a3 100644
--- a/scripts/libmakepkg/util/pkgbuild.sh.in
+++ b/scripts/libmakepkg/util/pkgbuild.sh.in
@@ -60,7 +60,7 @@ extract_global_variable() {
if (( isarray )); then
array_build ref "$attr"
- [[ ${ref[@]} ]] && array_build "$outputvar" "$attr"
+ (( ${#ref[@]} )) && array_build "$outputvar" "$attr"
else
[[ ${!attr} ]] && printf -v "$outputvar" %s "${!attr}"
fi
@@ -144,7 +144,7 @@ get_pkgbuild_all_split_attributes() {
done
done
- [[ ${all_list[@]} ]] && array_build "$outputvar" all_list
+ (( ${#all_list[@]} )) && array_build "$outputvar" all_list
}
##
--
2.19.1
3
4
[pacman-dev] [GIT] The official pacman repository branch, master, updated. v5.1.1-51-gb5d62d2c
by Allan McRae 21 Oct '18
by Allan McRae 21 Oct '18
21 Oct '18
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "The official pacman repository".
The branch, master has been updated
via b5d62d2c91a2caf5c18945921cdf12af6f36b2d4 (commit)
via 3561c872ca0980c76442fcbf3985cc92a8f572f7 (commit)
via 882e707e40bbade0111cf3bdedbdac4d4b70453b (commit)
via b5191ea140386dd9b73e4509ffa9a6d347c1b5fa (commit)
via e12d03217430500be269392463876440210f7916 (commit)
via ea877c596bc380acd608468e4e38186ac0252197 (commit)
via c887d2cf00d7c2238edd1d317b8c887e774b6d3f (commit)
via ac959bb9c6ce549047a954109ae825158855e386 (commit)
via 9886566abb375043740167ce5066f1a186c71176 (commit)
via 2c91d08e62dd13979192df4a0b2ca76bde87cfd0 (commit)
via 79a528735ee198ac880b65d946cfde9181872b44 (commit)
via 02255fd97e831854d1f29e6fac687a4a508f44fa (commit)
via 8c9046e6042fd23bf6a1bb204062fc644c322689 (commit)
via afb9c0140fd6949ede64cc1a304e9349772fca04 (commit)
via ffde85aadfe0e08fb710102d0a547335e9d1a200 (commit)
via d96d0ffe7c88d9521a9e6cdd65939e9a20733cdf (commit)
from 7afe51171fe063bf3031cc68fc8c7ac914a01de2 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit b5d62d2c91a2caf5c18945921cdf12af6f36b2d4
Author: Eli Schwartz <eschwartz(a)archlinux.org>
Date: Thu Jun 28 13:19:43 2018 -0400
Port scripts to use libmakepkg's messaging code.
Remove all remnants of library/{output_format,term_colors}.sh
Signed-off-by: Eli Schwartz <eschwartz(a)archlinux.org>
Signed-off-by: Allan McRae <allan(a)archlinux.org>
commit 3561c872ca0980c76442fcbf3985cc92a8f572f7
Author: Eli Schwartz <eschwartz(a)archlinux.org>
Date: Thu Jun 28 13:19:42 2018 -0400
message.sh: add modifications from output_format.sh
In the spirit of making libmakepkg more useful as a library, and,
critically, *using* that library for additional pacman scripts, we
should include all of output_format.sh and term_colors.sh directly in
libmakepkg and hopefully stop having to embed additional copies in e.g.
repo-add via m4 macros.
Signed-off-by: Eli Schwartz <eschwartz(a)archlinux.org>
Signed-off-by: Allan McRae <allan(a)archlinux.org>
commit 882e707e40bbade0111cf3bdedbdac4d4b70453b
Author: Eli Schwartz <eschwartz(a)archlinux.org>
Date: Thu Jun 28 13:19:41 2018 -0400
makepkg: send messages to stdout rather than stderr
This behavior is confusing, since it means absolutely everything goes to
stderr and makepkg itself is a quiet program that produces no expected
output???
The only situation where messages should go to stderr rather than
stdout, is with --geninteg which is meant to return the checksums on
stdout (but we don't want to totally get rid of status messages when
redirecting the results elsewhere, or, worse, redirect status messages
to a PKGBUILD). For this specific case, redirect message output to
stderr in the --geninteg callers directly.
Implements FS#17173
Signed-off-by: Eli Schwartz <eschwartz(a)archlinux.org>
Signed-off-by: Allan McRae <allan(a)archlinux.org>
commit b5191ea140386dd9b73e4509ffa9a6d347c1b5fa
Author: Eli Schwartz <eschwartz(a)archlinux.org>
Date: Tue Aug 21 10:15:12 2018 -0400
makepkg: use builtin globbing to print files in package
- it comes with free collation when moving the LC_ALL declaration up a bit;
this fixes a bug where the .FILES were not being properly sorted and
their order depended on directory creation order, which broke
reproducible builds in the wild.
- it handles sorting null-delimited output everywhere, without sort -z;
this lets us get rid of sed hacks
- it is faster than invoking multiple find subprocesses
- dotfiles can be automatically printed *and the C locale sorts them first*
with a single ** glob
Signed-off-by: Eli Schwartz <eschwartz(a)archlinux.org>
Signed-off-by: Allan McRae <allan(a)archlinux.org>
commit e12d03217430500be269392463876440210f7916
Author: Eli Schwartz <eschwartz(a)archlinux.org>
Date: Mon Aug 13 21:20:56 2018 -0400
makepkg: use bash 4.4 to localize `set` without explicitly saving/restoring
Signed-off-by: Eli Schwartz <eschwartz(a)archlinux.org>
Signed-off-by: Allan McRae <allan(a)archlinux.org>
commit ea877c596bc380acd608468e4e38186ac0252197
Author: Eli Schwartz <eschwartz(a)archlinux.org>
Date: Fri Sep 7 11:58:53 2018 -0400
bash-completion: disable completions for pacman --search operations
We don't need exact package name completions for something that expects a
regular expression *search*, which is what we currently do. If you want
a package name completion for a search, you don't need the search.
This change is consistent with the current state of zsh completions.
Fixes FS#59965
Signed-off-by: Eli Schwartz <eschwartz(a)archlinux.org>
Signed-off-by: Allan McRae <allan(a)archlinux.org>
commit c887d2cf00d7c2238edd1d317b8c887e774b6d3f
Author: Eli Schwartz <eschwartz(a)archlinux.org>
Date: Fri Sep 7 11:58:52 2018 -0400
bash-completion: don't complete filenames when they're not wanted
Filename completion should only be generated for makepkg, when using the
options -p or --config... which means we should offer option completions
by default.
Filename completion for pacman, should not be generated when using -Qu,
or -F without -o.
Signed-off-by: Eli Schwartz <eschwartz(a)archlinux.org>
Signed-off-by: Allan McRae <allan(a)archlinux.org>
commit ac959bb9c6ce549047a954109ae825158855e386
Author: Andrew Gregory <andrew.gregory.8(a)gmail.com>
Date: Fri Oct 12 19:16:53 2018 -0700
handle EINTR while polling scripts/hooks
If poll() is interrupted by a signal, alpm was closing the socket it
uses for listening to script/hook output. This would drop script output
at the least and kill the script at the worst.
Fixes FS#60396
Signed-off-by: Andrew Gregory <andrew.gregory.8(a)gmail.com>
Signed-off-by: Allan McRae <allan(a)archlinux.org>
commit 9886566abb375043740167ce5066f1a186c71176
Author: Andrew Gregory <andrew.gregory.8(a)gmail.com>
Date: Wed Oct 3 00:42:38 2018 -0700
reset signal handlers before running scripts/hooks
Front-ends or libraries may set signals to be ignored, which gets
inherited across fork and exec. This can cause scripts to malfunction
if they expect the signal. To make matters worse, scripts written in
bash can't reset signals that were ignored when bash was started.
Fixes FS#56756
Signed-off-by: Andrew Gregory <andrew.gregory.8(a)gmail.com>
Signed-off-by: Allan McRae <allan(a)archlinux.org>
commit 2c91d08e62dd13979192df4a0b2ca76bde87cfd0
Author: morganamilo <morganamilo(a)gmail.com>
Date: Tue Oct 16 18:49:23 2018 +0100
libmakepkg: fix linting arrays of empty strings
[[ ${array[@]} ]] will resolve to false if array only contains empty
strings. This means that values such as "depends=('')" can be inserted
into a pkgbuild and bypass the linting.
This causes makepkg to successfully build the package while pacman
refuses to install it because of the unmet dependency on ''.
Instead check the length of the array.
Signed-off-by: morganamilo <morganamilo(a)gmail.com>
Signed-off-by: Allan McRae <allan(a)archlinux.org>
commit 79a528735ee198ac880b65d946cfde9181872b44
Author: Dave Reisner <dreisner(a)archlinux.org>
Date: Mon Aug 20 20:52:34 2018 -0400
Drop vestiges of SIZECMD
SIZECMD was replaced in 1af766987f with a POSIX solution, and this token
is no longer used/needed.
commit 02255fd97e831854d1f29e6fac687a4a508f44fa
Author: morganamilo <morganamilo(a)gmail.com>
Date: Wed Oct 17 16:40:47 2018 +0100
libalpm: process needed before group selection
When --needed is used, up to date packages are now filtered out
before showing the group select.
Fixes FS#22870.
Signed-off-by: morganamilo <morganamilo(a)gmail.com>
commit 8c9046e6042fd23bf6a1bb204062fc644c322689
Author: morganamilo <morganamilo(a)gmail.com>
Date: Sat Oct 20 14:58:52 2018 +0100
pacman: don't error when a group exists but all packages are ignored
Currently when attempting to sync a group where all packages are
ignored, either by ignorepkg, ignoregroup or --needed, pacman
will error with "target not found".
Instead, if a group has no packages check if the group exists
before throwing an error.
Signed-off-by: morganamilo <morganamilo(a)gmail.com>
commit afb9c0140fd6949ede64cc1a304e9349772fca04
Author: Dave Reisner <dreisner(a)archlinux.org>
Date: Sun Aug 19 21:12:33 2018 -0400
Port pactest to python3
Use BytesIO instead of StringIO, and ensure that we unicode-encode data
where needed.
commit ffde85aadfe0e08fb710102d0a547335e9d1a200
Author: Olivier Brunel <jjk(a)jjacky.com>
Date: Wed Oct 17 17:11:01 2018 +0200
alpm: Fix SIGINT handling re: aborting download
Upon receiving SIGINT a flag is set to abort the (curl) download.
However, since it was never reset/initialized, if a front-end doesn't
actually exit on SIGINT, and later tries any operation that needs to
perform a new download, said download would always get aborted right
away due to the flag not having been reset.
commit d96d0ffe7c88d9521a9e6cdd65939e9a20733cdf
Author: Olivier Brunel <jjk(a)jjacky.com>
Date: Tue Oct 9 18:29:05 2018 +0200
alpm: Do not raise SIGINT when filesize goes over limit
Variable dload_interrupted is used both to abort a download because
SIGINT was caught, and when a file limit is reached. But raising SIGINT
is only meant to happen in the first case.
Signed-off-by: Olivier Brunel <jjk(a)jjacky.com>
-----------------------------------------------------------------------
Summary of changes:
configure.ac | 2 +-
lib/libalpm/dload.c | 3 +-
lib/libalpm/sync.c | 11 ++++++++
lib/libalpm/util.c | 30 +++++++++++++++++++-
scripts/Makefile.am | 21 ++++----------
scripts/completion/bash_completion.in | 20 ++++++++++----
.../libmakepkg/integrity/generate_checksum.sh.in | 2 +-
scripts/libmakepkg/util/message.sh.in | 14 ++++++++--
scripts/libmakepkg/util/pkgbuild.sh.in | 4 +--
scripts/library/README | 10 -------
scripts/library/output_format.sh | 32 ----------------------
scripts/library/term_colors.sh | 21 --------------
scripts/makepkg.sh.in | 15 ++++++----
scripts/pacman-db-upgrade.sh.in | 12 +++++---
scripts/pacman-key.sh.in | 12 +++++---
scripts/pkgdelta.sh.in | 12 +++++---
scripts/po/POTFILES.in | 2 --
scripts/repo-add.sh.in | 14 ++++++++--
src/pacman/sync.c | 18 ++++++++++++
test/pacman/pactest.py | 5 ++--
test/pacman/pmdb.py | 4 +--
test/pacman/pmpkg.py | 6 ++--
test/pacman/tests/TESTS | 2 ++
test/pacman/tests/scriptlet-signal-handling.py | 15 ++++++++++
test/pacman/tests/scriptlet-signal-reset.py | 11 ++++++++
test/pacman/util.py | 2 +-
26 files changed, 175 insertions(+), 125 deletions(-)
delete mode 100644 scripts/library/output_format.sh
delete mode 100644 scripts/library/term_colors.sh
create mode 100644 test/pacman/tests/scriptlet-signal-handling.py
create mode 100644 test/pacman/tests/scriptlet-signal-reset.py
hooks/post-receive
--
The official pacman repository
1
0
[pacman-dev] [PATCH 1/2] bash-completion: don't complete filenames when they're not wanted
by Eli Schwartz 21 Oct '18
by Eli Schwartz 21 Oct '18
21 Oct '18
Filename completion should only be generated for makepkg, when using the
options -p or --config... which means we should offer option completions
by default.
Filename completion for pacman, should not be generated when using -Qu,
or -F without -o.
Signed-off-by: Eli Schwartz <eschwartz(a)archlinux.org>
---
scripts/completion/bash_completion.in | 18 ++++++++++++------
1 file changed, 12 insertions(+), 6 deletions(-)
diff --git a/scripts/completion/bash_completion.in b/scripts/completion/bash_completion.in
index d99fba53..31b41f71 100644
--- a/scripts/completion/bash_completion.in
+++ b/scripts/completion/bash_completion.in
@@ -71,10 +71,13 @@ _pacman_key() {
}
_makepkg() {
+ compopt +o default
local cur opts prev
COMPREPLY=()
_get_comp_words_by_ref cur prev
- if [[ $cur = -* && ! $prev =~ ^-(-(config|help|key|version)$|\w*[Vhp]) ]]; then
+ if [[ $prev = @(-p|--config) ]]; then
+ compopt -o default
+ elif [[ ! $prev =~ ^-(-(config|help|key|version)$|\w*[Vh]) ]]; then
opts=('allsource asdeps check clean cleanbuild config force geninteg help
holdver ignorearch install key log needed noarchive nobuild nocheck
nocolor noconfirm nodeps noextract noprepare noprogressbar nosign
@@ -101,6 +104,7 @@ _pacman_repo_list() {
}
_pacman() {
+ compopt -o default
local common core cur database files prev query remove sync upgrade o
COMPREPLY=()
_get_comp_words_by_ref cur prev
@@ -131,12 +135,14 @@ _pacman() {
D|R)
_pacman_pkg Qq;;
F)
- _arch_incomp 'l list' && _pacman_pkg Slq
- ;;
+ { _arch_incomp 'l list' && _pacman_pkg Slq ; } ||
+ _arch_incomp 'o owns' ||
+ compopt +o default;;
Q)
{ _arch_incomp 'g groups' && _pacman_pkg Qg sort; } ||
{ _arch_incomp 'p file' && _pacman_file; } ||
- _arch_incomp 'o owns' || _arch_incomp 'u upgrades' ||
+ { _arch_incomp 'u upgrades' && compopt +o default; } ||
+ _arch_incomp 'o owns' ||
_pacman_pkg Qq;;
S)
{ _arch_incomp 'g groups' && _pacman_pkg Sg; } ||
@@ -153,8 +159,8 @@ _pacman_file() {
compopt -o filenames; _filedir 'pkg.tar*'
}
-complete -F _pacman -o default pacman
-complete -F _makepkg -o default makepkg
+complete -F _pacman pacman
+complete -F _makepkg makepkg
complete -F _pacman_key -o default pacman-key
# ex:et ts=2 sw=2 ft=sh
--
2.18.0
2
2
21 Oct '18
If poll() is interrupted by a signal, alpm was closing the socket it
uses for listening to script/hook output. This would drop script output
at the least and kill the script at the worst.
Fixes FS#60396
Signed-off-by: Andrew Gregory <andrew.gregory.8(a)gmail.com>
---
lib/libalpm/util.c | 10 +++++++++-
test/pacman/tests/TESTS | 1 +
test/pacman/tests/scriptlet-signal-handling.py | 15 +++++++++++++++
3 files changed, 25 insertions(+), 1 deletion(-)
create mode 100644 test/pacman/tests/scriptlet-signal-handling.py
diff --git a/lib/libalpm/util.c b/lib/libalpm/util.c
index eaf85e93..d33eef2a 100644
--- a/lib/libalpm/util.c
+++ b/lib/libalpm/util.c
@@ -665,6 +665,7 @@ int _alpm_run_chroot(alpm_handle_t *handle, const char *cmd, char *const argv[],
ssize_t olen = 0, ilen = 0;
nfds_t nfds = 2;
struct pollfd fds[2], *child2parent = &(fds[0]), *parent2child = &(fds[1]);
+ int poll_ret;
child2parent->fd = child2parent_pipefd[TAIL];
child2parent->events = POLLIN;
@@ -685,7 +686,14 @@ int _alpm_run_chroot(alpm_handle_t *handle, const char *cmd, char *const argv[],
#define STOP_POLLING(p) do { close(p->fd); p->fd = -1; } while(0)
while((child2parent->fd != -1 || parent2child->fd != -1)
- && poll(fds, nfds, -1) > 0) {
+ && (poll_ret = poll(fds, nfds, -1)) != 0) {
+ if(poll_ret == -1) {
+ if(errno == EINTR) {
+ continue;
+ } else {
+ break;
+ }
+ }
if(child2parent->revents & POLLIN) {
if(_alpm_chroot_read_from_child(handle, child2parent->fd,
ibuf, &ilen, sizeof(ibuf)) != 0) {
diff --git a/test/pacman/tests/TESTS b/test/pacman/tests/TESTS
index 5deb93c4..dc0b4ec3 100644
--- a/test/pacman/tests/TESTS
+++ b/test/pacman/tests/TESTS
@@ -150,6 +150,7 @@ TESTS += test/pacman/tests/replace102.py
TESTS += test/pacman/tests/replace103.py
TESTS += test/pacman/tests/replace104.py
TESTS += test/pacman/tests/replace110.py
+TESTS += test/pacman/tests/scriptlet-signal-handling.py
TESTS += test/pacman/tests/scriptlet-signal-reset.py
TESTS += test/pacman/tests/scriptlet001.py
TESTS += test/pacman/tests/scriptlet002.py
diff --git a/test/pacman/tests/scriptlet-signal-handling.py b/test/pacman/tests/scriptlet-signal-handling.py
new file mode 100644
index 00000000..e65df55b
--- /dev/null
+++ b/test/pacman/tests/scriptlet-signal-handling.py
@@ -0,0 +1,15 @@
+self.description = "Handle signal interrupts while running scriptlets/hooks"
+
+p1 = pmpkg("dummy")
+p1.install['post_install'] = """
+ kill -INT $PPID # send an arbitrary signal that pacman catches
+ sleep 1 # give alpm time to close the socket if EINTR was not handled
+ echo to-parent # if the interrupt is not handled this will die with SIGPIPE
+ echo success > interrupt_was_handled
+ """
+self.addpkg(p1)
+
+self.args = "-U %s" % p1.filename()
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("FILE_EXIST=interrupt_was_handled")
--
2.19.0
2
1
[pacman-dev] [PATCH] reset signal handlers before running scripts/hooks
by Andrew Gregory 21 Oct '18
by Andrew Gregory 21 Oct '18
21 Oct '18
Front-ends or libraries may set signals to be ignored, which gets
inherited across fork and exec. This can cause scripts to malfunction
if they expect the signal. To make matters worse, scripts written in
bash can't reset signals that were ignored when bash was started.
Fixes FS#56756
Signed-off-by: Andrew Gregory <andrew.gregory.8(a)gmail.com>
---
Hopefully nobody ignores or depends on signals outside of the POSIX
list. As far as I can tell, the only way to reset all signal handlers
is to iterate over the entire range of positive integers.
lib/libalpm/util.c | 20 ++++++++++++++++++++
test/pacman/tests/TESTS | 1 +
test/pacman/tests/scriptlet-signal-reset.py | 11 +++++++++++
3 files changed, 32 insertions(+)
create mode 100644 test/pacman/tests/scriptlet-signal-reset.py
diff --git a/lib/libalpm/util.c b/lib/libalpm/util.c
index a06f5bfd..eaf85e93 100644
--- a/lib/libalpm/util.c
+++ b/lib/libalpm/util.c
@@ -548,6 +548,25 @@ static int _alpm_chroot_read_from_child(alpm_handle_t *handle, int fd,
return 0;
}
+static void _alpm_reset_signals(void)
+{
+ /* reset POSIX defined signals (see signal.h) */
+ /* there are likely more but there is no easy way
+ * to get the full list of valid signals */
+ int *i, signals[] = {
+ SIGABRT, SIGALRM, SIGBUS, SIGCHLD, SIGCONT, SIGFPE, SIGHUP, SIGILL,
+ SIGINT, SIGKILL, SIGPIPE, SIGQUIT, SIGSEGV, SIGSTOP, SIGTERM, SIGTSTP,
+ SIGTTIN, SIGTTOU, SIGUSR1, SIGUSR2, SIGPOLL, SIGPROF, SIGSYS, SIGTRAP,
+ SIGURG, SIGVTALRM, SIGXCPU, SIGXFSZ,
+ 0
+ };
+ struct sigaction def;
+ def.sa_handler = SIG_DFL;
+ for(i = signals; *i; i++) {
+ sigaction(*i, &def, NULL);
+ }
+}
+
/** Execute a command with arguments in a chroot.
* @param handle the context handle
* @param cmd command to execute
@@ -633,6 +652,7 @@ int _alpm_run_chroot(alpm_handle_t *handle, const char *cmd, char *const argv[],
exit(1);
}
umask(0022);
+ _alpm_reset_signals();
execv(cmd, argv);
/* execv only returns if there was an error */
fprintf(stderr, _("call to execv failed (%s)\n"), strerror(errno));
diff --git a/test/pacman/tests/TESTS b/test/pacman/tests/TESTS
index b11cb511..5deb93c4 100644
--- a/test/pacman/tests/TESTS
+++ b/test/pacman/tests/TESTS
@@ -150,6 +150,7 @@ TESTS += test/pacman/tests/replace102.py
TESTS += test/pacman/tests/replace103.py
TESTS += test/pacman/tests/replace104.py
TESTS += test/pacman/tests/replace110.py
+TESTS += test/pacman/tests/scriptlet-signal-reset.py
TESTS += test/pacman/tests/scriptlet001.py
TESTS += test/pacman/tests/scriptlet002.py
TESTS += test/pacman/tests/sign001.py
diff --git a/test/pacman/tests/scriptlet-signal-reset.py b/test/pacman/tests/scriptlet-signal-reset.py
new file mode 100644
index 00000000..27246d12
--- /dev/null
+++ b/test/pacman/tests/scriptlet-signal-reset.py
@@ -0,0 +1,11 @@
+self.description = "Reset signals before running scriptlets/hooks"
+
+p1 = pmpkg("dummy")
+# check if SIGPIPE is ignored, it should be fatal, but GPGME ignores it
+p1.install['post_install'] = "kill -PIPE $$; echo fail > sigpipe_was_ignored"
+self.addpkg(p1)
+
+self.args = "-U %s" % p1.filename()
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("!FILE_EXIST=sigpipe_was_ignored")
--
2.19.0
2
1
[pacman-dev] [GIT] The official pacman repository annotated tag, v3.0.0-rc2, updated. v3.0.0-rc2
by Andrew Gregory 20 Oct '18
by Andrew Gregory 20 Oct '18
20 Oct '18
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "The official pacman repository".
The annotated tag, v3.0.0-rc2 has been updated
to fc4cd3864aae4edd5835116d9191b48f60ffa4a4 (tag)
from b977b9c030861decd22376e4d2a9147e830ebfae (which is now obsolete)
tagging 9e3a1853451230d887c3c89f49f04e502fb69621 (commit)
replaces v3.0.0-rc1
tagged by Andrew Gregory
on Sat Oct 20 12:53:22 2018 -0700
- Log -----------------------------------------------------------------
replaces broken tag b977b9c030861decd22376e4d2a9147e830ebfae
-----BEGIN PGP SIGNATURE-----
iQEzBAABCAAdFiEEuBUbEXA3eBCVUUynu9/8kjBrESEFAlvLh7IACgkQu9/8kjBr
ESFJ9QgAgulpF3KQDRNRgGIpoIlblE8U0H6AziEr+lG3RRUGZs4gxJybD2aMkcrB
KSQ0L4dTHfcQ1d//d+9N2TnEf60erz+ryC+lBDzNenqZ4ocLQwiYeRCzyc8DqIoU
7Rl8mFgv0IB+4IOh5r9nPFzsGqV1UJkTjOP5guHVsy7U/1ZbXEEjhBUwkhWPfpke
3QV+7T2I2oq8aFMm6Xx30WuOIUeFpjQ+HzyI3evVWQW/B3sL5CsTm/iyav3MaAZs
rtCrGkNpfH1EI2+N8WW/sA6ZON+LpnEoUnovaYD2wU2KRlnZDc5sZt3jXp9ETBvp
poKY0EgIJulQ5US59AdIWg2zWKDfSw==
=oJsw
-----END PGP SIGNATURE-----
Aaron Griffin (7):
* Fixed an issue with globbing the --test argument
Added this test to check the XferCommand functionality
* Fix the double package name URL when using XferCommand
* Bug fix for makepkg dependency testing. This requires that we
* Updated -V output to include the 2007 copyright date.
* Two fixes when running under a new root (-r|--root)
* Fixed an error with 'cascade' removal due to creation of a new pmpkg_t struct
Dan McGee (33):
* rankmirrors updates from Scott Horowitz <stonecrest(a)gmail.com>.
* Removed a mirrorlist that codemac says is quite outdated.
* Failure to #include config.h cost us here, we lost all NLS in alpm.c.
This commit looks much more monumental than it is. Almost all just #include
* Added missing header include guards in md5.h and sha1.h.
Trying to fix up this autotools stuff a bit more.
* Remove sha1 checksums for now from the INTEGRITY_CHECK array.
* Updated Italian translation
* Fix FS #6534- unclear IgnorePkg message. Sorry translators, had to update
* Sorry tranlators, another string update. .pacorig was displayed twice in
* Slight updates of Hungarian translation
* -Qs was returning an error if no package found, which is not the same behavior as -Ss.
* Oops, that last commit had some debug stuff in it. Removed it and added
* Updated Italian translation
* Added a readme file to the contrib/ directory.
* Updated Brazilian Portuguese translation
* Updated German translation
* Updated pot files for hopefully the last time before release.
* Slight updates to NEWS file.
* Mark a function as static that is only used in deptest.c.
* Updated Italian translation
* Added confirmation step to makepkg -C operation to ensure user is deleting
* Another slight update, getting rid of -rf flags and clarifying a message.
* Updated Italian translation
* Added Russian language translation. Thanks!
* Fix group comparison issue and associated compilation warnings by using
* Updated Hungarian translation, thanks!
* Updates to Hungarian translation from Nagy, mostly cleanup stuff.
* Fixed -Qil regression, now both flags are honored. (FS #1355)
* Removed ${CFLAGS} from Makefile.am(s) as it was causing all CFLAGS to be
* Fix an issue where the same dependency was recorded multiple times in the
* Fix wrong filesize being recorded to local DB. Reported by Andreas Radke.
* Noted a misspelling for later (after we are not in string freeze).
Jürgen Hötzel (1):
fixed string comparison callback (patch from Nagy Gabor)
-----------------------------------------------------------------------
hooks/post-receive
--
The official pacman repository
1
0