1
0
forked from mirrors/pacman

Compare commits

..

10 Commits

Author SHA1 Message Date
Allan McRae
7175062526 Store and read name of alternatives
Add the names of supplied alternatives to the .PKGINFO file.  Read and store
these values in libalpm.  This information is currently not used anywhere.

Signed-off-by: Allan McRae <allan@archlinux.org>
2021-12-12 11:54:51 +10:00
Allan McRae
7ceee8805b makepkg: add basic support for alternatives
Alternatives are specified in makepkg via (e.g.):

alternative=('sh')

There should be a file (e.g.) sh.alternative alongside the PKGBUILD containing
a list of symlinks to be created with the alternative is active.  This file is
stored in the root of the package as (e.g.) .ALTERNATIVE.sh.

Signed-off-by: Allan McRae <allan@archlinux.org>
2021-12-12 11:54:49 +10:00
Allan McRae
d21fb58da3 Gitlab CI: add --werror to debug build
Catch build warnings in the CI.

Signed-off-by: Allan McRae <allan@archlinux.org>
2021-11-21 09:54:56 -08:00
Allan McRae
5352367022 Prevent translation of curl
Signed-off-by: Allan McRae <allan@archlinux.org>
2021-11-20 12:39:42 -08:00
morganamilo
5287cc7251 alpm: fix wrong access() being used
When removing files we check _alpm_access() to see if we can write
(delete) the file. If not, we check if the file exists because if the
file does not exist then we don't actually need to remove it so there's
no issue.

However the second call uses acess() instead of _alpm_access() which
does not the rootdir into account.
2021-11-20 12:39:22 -08:00
Evangelos Foutras
fed522775d makepkg.conf: Pass -q as the first option to curl
As per curl(1), the -q (--disable) option must be first on the command
line to disable reading the curlrc config file. Without being first it
does not appear to have any effect.

Signed-off-by: Evangelos Foutras <evangelos@foutrelis.com>
2021-11-20 12:38:57 -08:00
morganamilo
b0a2fd75b2 Update mailing list url
change pacman-dev@archlinux.org to pacmandev@lists.archlinux.org

Most of this is copyright notices but this also fixes FS#72129 by
updating the address in docs/index.asciidoc.
2021-11-20 12:38:25 -08:00
Carlo Teubner
806ccd90ed "pacman -Q --changelog": fix writing uninit'd mem
Previously, when printing a package changelog to stdout, we would write
chunks of data that were not necessarily nul-terminated to stdout using
a function (fputs) which requires the input string to be nul-terminated.

On my system, this would result in occasional garbage characters showing
up in the "pacman -Qc" output.

Fix this by never nul-terminating the chunk, and using the fwrite()
function which takes an explicit input size and does not require a
nul-terminated string.

Signed-off-by: Carlo Teubner <carlo@cteubner.net>
2021-11-20 12:36:59 -08:00
Vladimir Panteleev
b242f5f24c libalpm: Log URLs when retrying
Allow finding which mirror was used to fetch a file.

This makes it a bit easier to debug situations in which mirrors serve
bad files with HTTP 200.

Signed-off-by: Vladimir Panteleev <archlinux@cy.md>
2021-11-20 12:36:29 -08:00
Andrew Gregory
529e208f39 remove YouCompleteMe config
Added, seemingly by accident, with meson in
51db84750e

Signed-off-by: Andrew Gregory <andrew.gregory.8@gmail.com>
2021-11-20 12:22:06 -08:00
15 changed files with 102 additions and 271 deletions

View File

@@ -27,7 +27,7 @@ arch:
arch-debug:
extends: .arch-test
script:
- meson --buildtype=debug build
- meson --buildtype=debug --werror build
- ninja -C build
- fakechroot meson test -C build

View File

@@ -1,250 +0,0 @@
#!/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
}

View File

@@ -402,8 +402,8 @@ All options and directives for the split packages default to the global values
given in the PKGBUILD. Nevertheless, the following ones can be overridden within
each split package's packaging function:
`pkgdesc`, `arch`, `url`, `license`, `groups`, `depends`, `optdepends`,
`provides`, `conflicts`, `replaces`, `backup`, `options`, `install`, and
`changelog`.
`provides`, `conflicts`, `replaces`, `backup`, `options`, `install`,
`changelog` and `alternative`.
Note that makepkg does not consider split package `depends` when checking
if dependencies are installed before package building and with `--syncdeps`.

View File

@@ -235,9 +235,8 @@ Transaction Options (apply to '-S', '-R' and '-U')
*\--print-format* <format>::
Specify a printf-like format to control the output of the '\--print'
operation. The possible attributes are: "%a" for arch, "%n" for pkgname,
"%v" for pkgver, "%l" for location, "%r" for repository, and "%s" for size.
Implies '\--print'.
operation. The possible attributes are: "%n" for pkgname, "%v" for pkgver,
"%l" for location, "%r" for repository, and "%s" for size. Implies '\--print'.
Upgrade Options (apply to '-S' and '-U')[[UO]]

View File

@@ -2555,6 +2555,12 @@ alpm_filelist_t *alpm_pkg_get_files(alpm_pkg_t *pkg);
*/
alpm_list_t *alpm_pkg_get_backup(alpm_pkg_t *pkg);
/** Returns the list of alternatives provided by the package
* @param pkg a pointer to package
* @return a reference to a list of char* objects
*/
alpm_list_t *alpm_pkg_get_alternatives(alpm_pkg_t *pkg);
/** Returns the database containing pkg.
* Returns a pointer to the alpm_db_t structure the package is
* originating from, or NULL if the package was loaded from a file.

View File

@@ -195,6 +195,12 @@ static alpm_list_t *_cache_get_backup(alpm_pkg_t *pkg)
return pkg->backup;
}
static alpm_list_t *_cache_get_alternatives(alpm_pkg_t *pkg)
{
LAZY_LOAD(INFRQ_DESC);
return pkg->alternatives;
}
/**
* Open a package changelog for reading. Similar to fopen in functionality,
* except that the returned 'file stream' is from the database.
@@ -349,6 +355,7 @@ static const struct pkg_operations local_pkg_ops = {
.get_replaces = _cache_get_replaces,
.get_files = _cache_get_files,
.get_backup = _cache_get_backup,
.get_alternatives = _cache_get_alternatives,
.changelog_open = _cache_changelog_open,
.changelog_read = _cache_changelog_read,
@@ -804,6 +811,8 @@ static int local_db_read(alpm_pkg_t *info, int inforeq)
READ_AND_SPLITDEP(info->conflicts);
} else if(strcmp(line, "%PROVIDES%") == 0) {
READ_AND_SPLITDEP(info->provides);
} else if(strcmp(line, "%ALTERNATIVES%") == 0) {
READ_AND_STORE_ALL(info->alternatives);
}
}
fclose(fp);
@@ -1040,6 +1049,15 @@ int _alpm_local_db_write(alpm_db_t *db, alpm_pkg_t *info, int inforeq)
write_deps(fp, "%CONFLICTS%", info->conflicts);
write_deps(fp, "%PROVIDES%", info->provides);
if(info->alternatives) {
fputs("%ALTERNATIVES%\n", fp);
for(lp = info->alternatives; lp; lp = lp->next) {
fputs(lp->data, fp);
fputc('\n', fp);
}
fputc('\n', fp);
}
fclose(fp);
fp = NULL;
}

View File

@@ -244,6 +244,8 @@ static int parse_descfile(alpm_handle_t *handle, struct archive *a, alpm_pkg_t *
CALLOC(backup, 1, sizeof(alpm_backup_t), return -1);
STRDUP(backup->name, ptr, FREE(backup); return -1);
newpkg->backup = alpm_list_add(newpkg->backup, backup);
} else if(strcmp(key, "alternative") == 0) {
newpkg->alternatives = alpm_list_add(newpkg->alternatives, strdup(ptr));
} else if(strcmp(key, "force") == 0) {
/* deprecated, skip it */
} else if(strcmp(key, "makepkgopt") == 0) {

View File

@@ -493,8 +493,8 @@ static int curl_check_finished_download(CURLM *curlm, CURLMsg *msg,
curl_gethost(payload->fileurl, hostname, sizeof(hostname));
curlerr = msg->data.result;
_alpm_log(handle, ALPM_LOG_DEBUG, "%s: curl returned result %d from transfer\n",
payload->remote_name, curlerr);
_alpm_log(handle, ALPM_LOG_DEBUG, "%s: %s returned result %d from transfer\n",
payload->remote_name, "curl", curlerr);
/* was it a success? */
switch(curlerr) {

View File

@@ -98,6 +98,7 @@ static alpm_list_t *_pkg_get_provides(alpm_pkg_t *pkg) { return pkg->provides;
static alpm_list_t *_pkg_get_replaces(alpm_pkg_t *pkg) { return pkg->replaces; }
static alpm_filelist_t *_pkg_get_files(alpm_pkg_t *pkg) { return &(pkg->files); }
static alpm_list_t *_pkg_get_backup(alpm_pkg_t *pkg) { return pkg->backup; }
static alpm_list_t *_pkg_get_alternatives(alpm_pkg_t *pkg) { return pkg->alternatives; }
static void *_pkg_changelog_open(alpm_pkg_t UNUSED *pkg)
{
@@ -162,6 +163,7 @@ const struct pkg_operations default_pkg_ops = {
.get_replaces = _pkg_get_replaces,
.get_files = _pkg_get_files,
.get_backup = _pkg_get_backup,
.get_alternatives = _pkg_get_alternatives,
.changelog_open = _pkg_changelog_open,
.changelog_read = _pkg_changelog_read,
@@ -418,6 +420,13 @@ alpm_list_t SYMEXPORT *alpm_pkg_get_backup(alpm_pkg_t *pkg)
return pkg->ops->get_backup(pkg);
}
alpm_list_t SYMEXPORT *alpm_pkg_get_alternatives(alpm_pkg_t *pkg)
{
ASSERT(pkg != NULL, return NULL);
pkg->handle->pm_errno = ALPM_ERR_OK;
return pkg->ops->get_alternatives(pkg);
}
alpm_db_t SYMEXPORT *alpm_pkg_get_db(alpm_pkg_t *pkg)
{
/* Sanity checks */
@@ -632,6 +641,7 @@ int _alpm_pkg_dup(alpm_pkg_t *pkg, alpm_pkg_t **new_ptr)
newpkg->optdepends = list_depdup(pkg->optdepends);
newpkg->conflicts = list_depdup(pkg->conflicts);
newpkg->provides = list_depdup(pkg->provides);
newpkg->alternatives = alpm_list_strdup(pkg->alternatives);
if(pkg->files.count) {
size_t filenum;
@@ -709,6 +719,7 @@ void _alpm_pkg_free(alpm_pkg_t *pkg)
free_deplist(pkg->provides);
alpm_list_free(pkg->removes);
_alpm_pkg_free(pkg->oldpkg);
FREELIST(pkg->alternatives);
if(pkg->origin == ALPM_PKG_FROM_FILE) {
FREE(pkg->origin_data.file);

View File

@@ -66,6 +66,7 @@ struct pkg_operations {
alpm_list_t *(*get_replaces) (alpm_pkg_t *);
alpm_filelist_t *(*get_files) (alpm_pkg_t *);
alpm_list_t *(*get_backup) (alpm_pkg_t *);
alpm_list_t *(*get_alternatives) (alpm_pkg_t *);
void *(*changelog_open) (alpm_pkg_t *);
size_t (*changelog_read) (void *, size_t, const alpm_pkg_t *, void *);
@@ -120,6 +121,7 @@ struct _alpm_pkg_t {
alpm_list_t *provides;
alpm_list_t *removes; /* in transaction targets only */
alpm_pkg_t *oldpkg; /* in transaction targets only */
alpm_list_t *alternatives;
const struct pkg_operations *ops;

View File

@@ -0,0 +1,41 @@
#!/bin/bash
#
# alternative.sh - Check the files associated with the 'alternative'
# array exist.
#
# Copyright (c) 2020 Pacman Development Team <pacman-dev@archlinux.org>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
[[ -n "$LIBMAKEPKG_LINT_PKGBUILD_ALTERNATIVE_SH" ]] && return
LIBMAKEPKG_LINT_PKGBUILD_ALTERNATIVE_SH=1
LIBRARY=${LIBRARY:-'@libmakepkgdir@'}
source "$LIBRARY/util/message.sh"
source "$LIBRARY/util/pkgbuild.sh"
source "$LIBRARY/lint_pkgbuild/util.sh"
lint_pkgbuild_functions+=('lint_alternative')
lint_alternative() {
local ret=0
check_files_exist 'alternative' "${alternative[@]/%/.alternative}" || ret=1
return $ret
}

View File

@@ -1,6 +1,7 @@
libmakepkg_module = 'lint_pkgbuild'
sources = [
'alternative.sh.in',
'arch.sh.in',
'arch_specific.sh.in',
'backup.sh.in',

View File

@@ -28,8 +28,8 @@ source "$LIBRARY/util/util.sh"
known_hash_algos=({ck,md5,sha{1,224,256,384,512},b2})
pkgbuild_schema_arrays=(arch backup checkdepends conflicts depends groups
license makedepends noextract optdepends options
pkgbuild_schema_arrays=(alternative arch backup checkdepends conflicts depends
groups license makedepends noextract optdepends options
provides replaces source validpgpkeys
"${known_hash_algos[@]/%/sums}")
@@ -42,7 +42,7 @@ pkgbuild_schema_arch_arrays=(checkdepends conflicts depends makedepends
pkgbuild_schema_package_overrides=(pkgdesc arch url license groups depends
optdepends provides conflicts replaces
backup options install changelog)
backup options install changelog alternative)
readonly -a known_hash_algos pkgbuild_schema_arrays \
pkgbuild_schema_strings pkgbuild_schema_arch_arrays \

View File

@@ -630,6 +630,7 @@ write_pkginfo() {
write_kv_pair "optdepend" "${optdepends[@]//+([[:space:]])/ }"
write_kv_pair "makedepend" "${makedepends[@]}"
write_kv_pair "checkdepend" "${checkdepends[@]}"
write_kv_pair "alternative" "${alternative[@]}"
}
write_buildinfo() {
@@ -710,6 +711,16 @@ create_package() {
fi
done
# check for alternative files
for i in ${alternative[@]}; do
msg2 "$(gettext "Adding %s file...")" "$i.alternative"
if ! cp "$startdir/$i.alternative" ".ALTERNATIVE.$i"; then
error "$(gettext "Failed to add %s file to package.")" "$i.alternative"
exit $E_MISSING_FILE
fi
chmod 644 ".ALTERNATIVE.$i"
done
# tar it up
local fullver=$(get_full_version)
local pkg_file="$PKGDEST/${pkgname}-${fullver}-${pkgarch}${PKGEXT}"

View File

@@ -1146,16 +1146,6 @@ void print_packages(const alpm_list_t *packages)
alpm_pkg_t *pkg = i->data;
char *string = strdup(config->print_format);
char *temp = string;
/* %a : arch */
if(strstr(temp, "%a")) {
const char *arch = alpm_pkg_get_arch(pkg);
if(arch == NULL) {
arch = "";
}
string = strreplace(temp, "%a", arch);
free(temp);
temp = string;
}
/* %n : pkgname */
if(strstr(temp, "%n")) {
string = strreplace(temp, "%n", alpm_pkg_get_name(pkg));