# Interface for retrieving source and binary package metadata # # Copyright (C) 2012, 2019 Patrick McDermott # # This file is part of opkbuild. # # opkbuild 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 3 of the License, or # (at your option) any later version. # # opkbuild 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 opkbuild. If not, see . _ob_package_dir= _ob_package_format= _ob_binary_packages= _ob_got_binary_packages=false _ob_source_parameters= _ob_binary_parameters= _ob_package_do() { local func="${1}" shift 1 || _ob_abort "_ob_${func}_${_ob_package_format}" "${@}" || return ${?} return 0 } ## @brief Initialize libopkbuild for a source package ## @details \fBob_init_package\fP() detects the version of and parses all ## metadata of a source package. This function must be called before ## any other functions that operate on package metadata. ## @operand dir req The root directory of the source package. ## @return Returns 0 on success or 1 if the source package version can't be ## detected or if the metadata can't be parsed. ## @stderr Prints error or warning messages on detection or parsing errors. ## @pure no This function sets internal global variables. ob_init_package() { local dir="${1}" shift 1 || _ob_abort _ob_package_dir="$(cd -- "${dir}" && pwd)" if [ -r "${_ob_package_dir}/format" ]; then case "$(cat -- "${_ob_package_dir}/format")" in 2.0) _ob_package_format='2' ;; esac fi if [ -z "${_ob_package_format}" ]; then _ob_error_msg 'unable_to_detect_package_format' return 1 fi _ob_binary_packages= _ob_package_do 'parse_package_metadata' || return ${?} return 0 } ## @brief Get a list of binary packages ## @details \fBob_get_binary_packages\fP() finds a source package's binary ## packages, optionally filtering for packages that build for a certain ## host architecture and/or platform. ## @option -a host_arch The architecture by which to filter binary packages. ## @option -a host_plat The platform by which to filter binary packages. ## @return Returns 0 on success. ## @stdout Prints the resulting list of binary packages. ## @stderr Prints warning messages on invalid binary package names and duplicate ## "clean" binary package names. ## @pure maybe This function caches a list of all binary packages to an internal ## global variable to save time and avoid repeating warning messages ## on subsequent invocations. It should therefore first be called ## outside a subshell, though this is not required. ob_get_binary_packages() { local opt= local host_arch= local host_plat= local pkg= local pkgs_clean= local pkg_clean= local pkgs= OPTIND=1 while getopts 'a:p:' opt; do case "${opt}" in a) host_arch="${OPTARG}" ;; p) host_plat="${OPTARG}" ;; ?) _ob_abort ;; esac done shift $((${OPTIND} - 1)) if ! ${_ob_got_binary_packages}; then _ob_package_do 'get_binary_packages' pkgs_clean=' ' for pkg in ${_ob_binary_packages}; do # Validate the name. if ! ob_validate_binary_name "${pkg}"; then _ob_warn_msg 'bad_binary_name' "${pkg}" continue fi # Make sure the "clean" name is unique. pkg_clean="$(printf '%s' "${pkg}" | tr 'a-z' 'A-Z' | \ tr -C 'A-Z0-9' '_')" case "${pkgs_clean}" in *" ${pkg_clean} "*) _ob_warn_msg 'duplicate_clean_binary_name' \ "${pkg_clean}" continue esac pkgs_clean="${pkgs_clean}${pkg_clean} " _ob_binary_packages="${_ob_binary_packages} ${pkgs}" done _ob_got_binary_packages=true fi pkgs='' for pkg in ${_ob_binary_packages}; do if [ -n "${host_arch}" ] && ! ob_arch_is_concerned \ "${host_arch}" "$(ob_get_binary_parameter \ "${pkg}" 'Architecture')"; then continue fi if [ -n "${host_plat}" ] && ! ob_plat_is_concerned \ "${host_plat}" "$(ob_get_binary_parameter \ "${pkg}" 'Platform')"; then continue fi pkgs="${pkgs} ${pkg}" done printf '%s ' ${pkgs} return 0 } ## @brief Get a source package field value ## @details \fBob_get_source_parameter\fP() gets the value of a source package ## field. ## @operand name req The name of the field. ## @return Returns 0 on success or 1 if \fIname\fP is invalid. ## @stdout Prints the source package field value. ## @pure yes This function has no side effects. ob_get_source_parameter() { local name="${1}" shift 1 || _ob_abort # Convert field name to uppercase and validate. case "${name}" in *[!A-Za-z0-9-]* | '') return 1 esac name="$(tr 'a-z-' 'A-Z_' <<-EOF ${name} EOF )" # TODO: Return error on no such field? eval "printf '%s' \"\${_OB_SRCFIELD_${name}-}\"" return 0 } ## @brief Get a binary package field value ## @details \fBob_get_binary_parameter\fP() gets the value of a binary package ## field. ## @operand package req The name of the binary package. ## @operand name req The name of the field. ## @return Returns 0 on success or 1 if \fIname\fP is invalid. ## @stdout Prints the binary package field value. ## @pure yes This function has no side effects. ob_get_binary_parameter() { local package="${1}" local name="${2}" shift 2 || _ob_abort if ! ob_validate_binary_name "${package}"; then return 1 fi # Convert package name to its uppercase "clean" form. package="$(printf '%s' "${package}" | tr 'a-z' 'A-Z' | \ tr -C 'A-Z0-9' '_')" # Convert field name to uppercase and validate. case "${name}" in *[!A-Za-z0-9-]* | '') return 1 esac name="$(tr 'a-z-' 'A-Z_' <<-EOF ${name} EOF )" # TODO: Return error on no such field? eval "printf '%s' \"\${_OB_BINFIELD_${package}_${name}-}\"" return 0 } ## @brief Get the documentation-providing binary package ## @details \fBob_get_doc_package\fP() gets the name of the binary package that ## will provide documentation files about the source package. ## @return Returns 0 on success or 1 if no or multiple packages are found to ## provide documentation files. ## @stdout Prints the documentation-providing binary package name. ## @pure yes This function has no side effects. ob_get_doc_package() { _ob_package_do 'get_doc_package' || return ${?} return 0 } ## @brief Get the source package documentation files table ## @details \fBob_get_doc_files\fP() gets the table of source package ## documentation files. The table consists of lines of space-separated ## source (relative to the build work area) and destination (relative ## to the source package documentation directory) file paths. ## @return Returns 0 on success. ## @stdout Prints the source package documentation files table. ## @pure yes This function has no side effects. ob_get_doc_files() { _ob_package_do 'get_doc_files' || return ${?} return 0 } ## @brief Set package substitution variables ## @details \fBob_set_package_substvars\fP() sets any substitution variables ## defined by a source package, as well as any standard substitution ## variables defined by the source package format, for later use by ## \fBob_substvars\fP(3). ## @operand pkg req The binary package for which to set substitution variables. ## @return Returns 0 on success. ## @stderr Prints error messages on parse errors. ## @pure no This function sets internal global variables. ob_set_package_substvars() { local pkg="${1}" shift 1 || _ob_abort _ob_package_do 'set_package_substvars' "${pkg}" || return ${?} return 0 } _ob_set_binary_packages() { local packages="${1}" shift 1 || _ob_abort _ob_binary_packages="${packages}" return 0 } _ob_set_source_parameter() { local name="${1}" local value="${2}" shift 2 || _ob_abort # Convert field name to uppercase and validate. case "${name}" in *[!A-Za-z0-9-]* | '') return 1 esac name="$(tr 'a-z-' 'A-Z_' <<-EOF ${name} EOF )" _ob_source_parameters="${_ob_source_parameters} ${name}" eval "_OB_SRCFIELD_${name}=\"\${value}\"" return 0 } _ob_set_binary_parameter() { local package="${1}" local name="${2}" local value="${3}" shift 3 || _ob_abort if ! ob_validate_binary_name "${package}"; then return 1 fi # Convert package name to its uppercase "clean" form. package="$(printf '%s' "${package}" | tr 'a-z' 'A-Z' | \ tr -C 'A-Z0-9' '_')" # Convert field name to uppercase and validate. case "${name}" in *[!A-Za-z0-9-]* | '') return 1 esac name="$(tr 'a-z-' 'A-Z_' <<-EOF ${name} EOF )" case " ${_ob_binary_parameters} " in *" ${name} "*) ;; *) _ob_binary_parameters="${_ob_binary_parameters} ${name}" ;; esac eval "_OB_BINFIELD_${package}_${name}=\"\${value}\"" return 0 }