From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from lists.gentoo.org (pigeon.gentoo.org [208.92.234.80]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by finch.gentoo.org (Postfix) with ESMTPS id CF13E1396D0 for ; Tue, 19 Sep 2017 11:08:36 +0000 (UTC) Received: from pigeon.gentoo.org (localhost [127.0.0.1]) by pigeon.gentoo.org (Postfix) with SMTP id 332F11FC117; Tue, 19 Sep 2017 11:08:36 +0000 (UTC) Received: from smtp.gentoo.org (smtp.gentoo.org [140.211.166.183]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by pigeon.gentoo.org (Postfix) with ESMTPS id F40B01FC117 for ; Tue, 19 Sep 2017 11:08:35 +0000 (UTC) Received: from oystercatcher.gentoo.org (unknown [IPv6:2a01:4f8:202:4333:225:90ff:fed9:fc84]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.gentoo.org (Postfix) with ESMTPS id D9B963415B7 for ; Tue, 19 Sep 2017 11:08:34 +0000 (UTC) Received: from localhost.localdomain (localhost [IPv6:::1]) by oystercatcher.gentoo.org (Postfix) with ESMTP id 13FFC9073 for ; Tue, 19 Sep 2017 11:08:33 +0000 (UTC) From: "Michał Górny" To: gentoo-commits@lists.gentoo.org Content-Transfer-Encoding: 8bit Content-type: text/plain; charset=UTF-8 Reply-To: gentoo-dev@lists.gentoo.org, "Michał Górny" Message-ID: <1505819306.59a1a0dda7300177a263eb1de347da493f09fdee.mgorny@gentoo> Subject: [gentoo-commits] repo/gentoo:master commit in: eclass/tests/, eclass/ X-VCS-Repository: repo/gentoo X-VCS-Files: eclass/eapi7-ver.eclass eclass/tests/eapi7-ver.sh eclass/tests/eapi7-ver_benchmark.sh X-VCS-Directories: eclass/tests/ eclass/ X-VCS-Committer: mgorny X-VCS-Committer-Name: Michał Górny X-VCS-Revision: 59a1a0dda7300177a263eb1de347da493f09fdee X-VCS-Branch: master Date: Tue, 19 Sep 2017 11:08:33 +0000 (UTC) Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-Id: Gentoo Linux mail X-BeenThere: gentoo-commits@lists.gentoo.org X-Archives-Salt: f548ac08-fbc8-4703-8899-6256fd2682d9 X-Archives-Hash: 57b6b576e2c0c8e3db1e4f2ec0513488 commit: 59a1a0dda7300177a263eb1de347da493f09fdee Author: Michał Górny gentoo org> AuthorDate: Fri Sep 8 11:12:30 2017 +0000 Commit: Michał Górny gentoo org> CommitDate: Tue Sep 19 11:08:26 2017 +0000 URL: https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=59a1a0dd eapi7-ver.eclass: 'Early adopter' version of EAPI 7 version manip EAPI 7 is introducing new version manipulation and comparison functions that aim to replace versionator.eclass. This eclass provides an 'early adopter' versions of those routines. It serves two goals: a. getting wider review and some real-life testing before the specification is set in stone, b. making it possible to adapt ebuilds to the new routines early, reducing the future work of EAPI 7 porting, c. improving cache generation speed (the rountines are roughly 15-20 times than versionator.eclass). For more details on the new logic, please see the eclass documentation. Long story short, we are introducing three functions: 1. ver_cut -- to get substrings of the version string, 2. ver_rs -- to replace version separators via indices, 3. ver_test -- to compare two version numbers. The third function is not implemented in the eclass. It's meant to reuse the algorithms from the package manager, and the final implementation will most likely reuse the code from the package manager (e.g. via IPC). The code has been initially written by Ulrich Müller. eclass/eapi7-ver.eclass | 190 ++++++++++++++++++++++++++++++++++++ eclass/tests/eapi7-ver.sh | 65 ++++++++++++ eclass/tests/eapi7-ver_benchmark.sh | 113 +++++++++++++++++++++ 3 files changed, 368 insertions(+) diff --git a/eclass/eapi7-ver.eclass b/eclass/eapi7-ver.eclass new file mode 100644 index 00000000000..1e8e3c5e55b --- /dev/null +++ b/eclass/eapi7-ver.eclass @@ -0,0 +1,190 @@ +# Copyright 1999-2017 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 + +# @ECLASS: eapi7-ver.eclass +# @MAINTAINER: +# PMS team +# @AUTHOR: +# Ulrich Müller +# Michał Górny +# @BLURB: Testing implementation of EAPI 7 version manipulators +# @DESCRIPTION: +# A stand-alone implementation of the version manipulation functions +# aimed for EAPI 7. Intended to be used for wider testing of +# the proposed functions and to allow ebuilds to switch to the new +# model early, with minimal change needed for actual EAPI 7. +# +# https://bugs.gentoo.org/482170 +# +# Note: version comparison function is not included currently. +# +# @ROFF .SS +# Version strings +# +# The functions support arbitrary version strings consisting of version +# components interspersed with (possibly empty) version separators. +# +# A version component can either consist purely of digits ([0-9]+) +# or purely of uppercase and lowercase letters ([A-Za-z]+). A version +# separator is either a string of any other characters ([^A-Za-z0-9]+), +# or it occurs at the transition between a sequence of letters +# and a sequence of digits, or vice versa. In the latter case, +# the version separator is an empty string. +# +# The version is processed left-to-right, and each successive component +# is assigned numbers starting with 1. The components are either split +# on version separators or on boundaries between digits and letters +# (in which case the separator between the components is empty). +# Version separators are assigned numbers starting with 1 for +# the separator between 1st and 2nd components. As a special case, +# if the version string starts with a separator, it is assigned index 0. +# +# Examples: +# +# @CODE +# 1.2b-alpha4 -> 1 . 2 '' b - alpha '' 4 +# c s c s c s c s c +# 1 1 2 2 3 3 4 4 5 +# +# .11. -> . 11 . +# s c s +# 0 1 1 +# @CODE +# +# @ROFF .SS +# Ranges +# +# A range can be specified as 'm' for m-th version component, 'm-' +# for all components starting with m-th or 'm-n' for components starting +# at m-th and ending at n-th (inclusive). If the range spans outside +# the version string, it is truncated silently. + +case ${EAPI:-0} in + 0|1|2|3|4|5) + die "${ECLASS}: EAPI=${EAPI:-0} not supported";; + 6) + ;; + *) + die "${ECLASS}: EAPI=${EAPI} unknown";; +esac + +# @FUNCTION: _ver_parse_range +# @USAGE: +# @INTERNAL +# @DESCRIPTION: +# Parse the range string , setting 'start' and 'end' variables +# to the appropriate bounds. and specify the appropriate +# lower and upper bound for the range; the user-specified value is +# truncated to this range. +_ver_parse_range() { + local range=${1} + local max=${2} + + [[ ${range} == [0-9]* ]] \ + || die "${FUNCNAME}: range must start with a number" + start=${range%-*} + [[ ${range} == *-* ]] && end=${range#*-} || end=${start} + if [[ ${end} ]]; then + [[ ${start} -le ${end} ]] \ + || die "${FUNCNAME}: end of range must be >= start" + [[ ${end} -le ${max} ]] || end=${max} + else + end=${max} + fi +} + +# @FUNCTION: _ver_split +# @USAGE: +# @INTERNAL +# @DESCRIPTION: +# Split the version string into separator-component array. +# Sets 'comp' to an array of the form: ( s_0 c_1 s_1 c_2 s_2 c_3... ) +# where s_i are separators and c_i are components. +_ver_split() { + local v=${1} LC_ALL=C + + comp=() + + # get separators and components + local s c + while [[ ${v} ]]; do + # cut the separator + s=${v%%[a-zA-Z0-9]*} + v=${v:${#s}} + # cut the next component; it can be either digits or letters + [[ ${v} == [0-9]* ]] && c=${v%%[^0-9]*} || c=${v%%[^a-zA-Z]*} + v=${v:${#c}} + + comp+=( "${s}" "${c}" ) + done +} + +# @FUNCTION: ver_cut +# @USAGE: [] +# @DESCRIPTION: +# Print the substring of the version string containing components +# defined by the and the version separators between them. +# Processes if specified, ${PV} otherwise. +# +# For the syntax of versions and ranges, please see the eclass +# description. +ver_cut() { + local range=${1} + local v=${2:-${PV}} + local start end + local -a comp + + _ver_split "${v}" + local max=$((${#comp[@]}/2)) + _ver_parse_range "${range}" "${max}" + + local IFS= + if [[ ${start} -gt 0 ]]; then + start=$(( start*2 - 1 )) + fi + echo "${comp[*]:start:end*2-start}" +} + +# @FUNCTION: ver_rs +# @USAGE: [ ...] [] +# @DESCRIPTION: +# Print the version string after substituting the specified version +# separators at with (string). Multiple ' ' +# pairs can be specified. Processes if specified, +# ${PV} otherwise. +# +# For the syntax of versions and ranges, please see the eclass +# description. +ver_rs() { + local v + (( ${#} & 1 )) && v=${@: -1} || v=${PV} + local start end i + local -a comp + + _ver_split "${v}" + local max=$((${#comp[@]}/2 - 1)) + + while [[ ${#} -ge 2 ]]; do + _ver_parse_range "${1}" "${max}" + for (( i = start*2; i <= end*2; i+=2 )); do + [[ ${i} -eq 0 && -z ${comp[i]} ]] && continue + comp[i]=${2} + done + shift 2 + done + + local IFS= + echo "${comp[*]}" +} + +# @FUNCTION: ver_test +# @USAGE: [] +# @DESCRIPTION: +# Check if the relation is true. If is not specified, +# default to ${PVR}. can be -gt, -ge, -eq, -ne, -le, -lt. +# Both versions must conform to the PMS version syntax (with optional +# revision parts), and the comparison is performed according to +# the algorithm specified in the PMS. +ver_test() { + die "${FUNCNAME}: not implemented" +} diff --git a/eclass/tests/eapi7-ver.sh b/eclass/tests/eapi7-ver.sh new file mode 100755 index 00000000000..8a96e4d29b1 --- /dev/null +++ b/eclass/tests/eapi7-ver.sh @@ -0,0 +1,65 @@ +#!/bin/bash +# Copyright 1999-2017 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 + +EAPI=6 + +source tests-common.sh + +inherit eapi7-ver + +teq() { + local expected=${1}; shift + + tbegin "${*} -> ${expected}" + local got=$("${@}") + [[ ${got} == ${expected} ]] + tend ${?} "returned: ${got}" +} + +txf() { + tbegin "XFAIL: ${*}" + local got=$("${@}" 2>&1) + [[ ${got} == die:* ]] + tend ${?} "function did not die" +} + +teq 1 ver_cut 1 1.2.3 +teq 1 ver_cut 1-1 1.2.3 +teq 1.2 ver_cut 1-2 1.2.3 +teq 2.3 ver_cut 2- 1.2.3 +teq 1.2.3 ver_cut 1- 1.2.3 +teq 3b ver_cut 3-4 1.2.3b_alpha4 +teq alpha ver_cut 5 1.2.3b_alpha4 +teq 1.2 ver_cut 1-2 .1.2.3 +teq .1.2 ver_cut 0-2 .1.2.3 +teq 2.3 ver_cut 2-3 1.2.3. +teq 2.3. ver_cut 2- 1.2.3. +teq 2.3. ver_cut 2-4 1.2.3. + +teq 1-2.3 ver_rs 1 - 1.2.3 +teq 1.2-3 ver_rs 2 - 1.2.3 +teq 1-2-3.4 ver_rs 1-2 - 1.2.3.4 +teq 1.2-3-4 ver_rs 2- - 1.2.3.4 +teq 1.2.3 ver_rs 2 . 1.2-3 +teq 1.2.3.a ver_rs 3 . 1.2.3a +teq 1.2-alpha-4 ver_rs 2-3 - 1.2_alpha4 +teq 1.23-b_alpha4 ver_rs 3 - 2 "" 1.2.3b_alpha4 +teq a1b_2-c-3-d4e5 ver_rs 3-5 _ 4-6 - a1b2c3d4e5 +teq .1-2.3 ver_rs 1 - .1.2.3 +teq -1.2.3 ver_rs 0 - .1.2.3 + +# truncating range +teq 1.2 ver_cut 0-2 1.2.3 +teq 2.3 ver_cut 2-5 1.2.3 +teq "" ver_cut 4 1.2.3 +teq "" ver_cut 0 1.2.3 +teq "" ver_cut 4- 1.2.3 +teq 1.2.3 ver_rs 0 - 1.2.3 +teq 1.2.3 ver_rs 3 . 1.2.3 +teq 1.2.3 ver_rs 3- . 1.2.3 +teq 1.2.3 ver_rs 3-5 . 1.2.3 + +txf ver_cut foo 1.2.3 +txf ver_rs -3 _ a1b2c3d4e5 +txf ver_rs 5-3 _ a1b2c3d4e5 diff --git a/eclass/tests/eapi7-ver_benchmark.sh b/eclass/tests/eapi7-ver_benchmark.sh new file mode 100755 index 00000000000..7e3c830fcb7 --- /dev/null +++ b/eclass/tests/eapi7-ver_benchmark.sh @@ -0,0 +1,113 @@ +#!/bin/bash +# Copyright 1999-2017 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 + +EAPI=6 + +source tests-common.sh + +inherit eapi7-ver versionator + +cutting() { + local x + for x in {1..1000}; do + ver_cut 1 1.2.3 + ver_cut 1-2 1.2.3 + ver_cut 2- 1.2.3 + ver_cut 1- 1.2.3 + ver_cut 3-4 1.2.3b_alpha4 + ver_cut 5 1.2.3b_alpha4 + ver_cut 1-2 .1.2.3 + ver_cut 0-2 .1.2.3 + ver_cut 2-3 1.2.3. + ver_cut 2- 1.2.3. + ver_cut 2-4 1.2.3. + done >/dev/null +} + +cutting_versionator() { + local x + for x in {1..100}; do + get_version_component_range 1 1.2.3 + get_version_component_range 1-2 1.2.3 + get_version_component_range 2- 1.2.3 + get_version_component_range 1- 1.2.3 + get_version_component_range 3-4 1.2.3b_alpha4 + get_version_component_range 5 1.2.3b_alpha4 + get_version_component_range 1-2 .1.2.3 + get_version_component_range 0-2 .1.2.3 + get_version_component_range 2-3 1.2.3. + get_version_component_range 2- 1.2.3. + get_version_component_range 2-4 1.2.3. + done >/dev/null +} + +replacing() { + local x + for x in {1..1000}; do + ver_rs 1 - 1.2.3 + ver_rs 2 - 1.2.3 + ver_rs 1-2 - 1.2.3.4 + ver_rs 2- - 1.2.3.4 + ver_rs 2 . 1.2-3 + ver_rs 3 . 1.2.3a + ver_rs 2-3 - 1.2_alpha4 + #ver_rs 3 - 2 "" 1.2.3b_alpha4 + #ver_rs 3-5 _ 4-6 - a1b2c3d4e5 + ver_rs 1 - .1.2.3 + ver_rs 0 - .1.2.3 + done >/dev/null +} + +replacing_versionator() { + local x + for x in {1..100}; do + replace_version_separator 1 - 1.2.3 + replace_version_separator 2 - 1.2.3 + replace_version_separator 1-2 - 1.2.3.4 + replace_version_separator 2- - 1.2.3.4 + replace_version_separator 2 . 1.2-3 + replace_version_separator 3 . 1.2.3a + replace_version_separator 2-3 - 1.2_alpha4 + #replace_version_separator 3 - 2 "" 1.2.3b_alpha4 + #replace_version_separator 3-5 _ 4-6 - a1b2c3d4e5 + replace_version_separator 1 - .1.2.3 + replace_version_separator 0 - .1.2.3 + done >/dev/null +} + +get_times() { + local factor=${1}; shift + echo "${*}" + local real=() + local user=() + + for x in {1..5}; do + while read tt tv; do + case ${tt} in + real) real+=( $(dc -e "${tv} ${factor} * p") );; + user) user+=( $(dc -e "${tv} ${factor} * p") );; + esac + done < <( ( time -p "${@}" ) 2>&1 ) + done + + [[ ${#real[@]} == 5 ]] || die "Did not get 5 real times" + [[ ${#user[@]} == 5 ]] || die "Did not get 5 user times" + + local sum + for v in real user; do + vr="${v}[*]" + sum=$(dc -e "${!vr} + + + + 3 k 5 / p") + + vr="${v}[@]" + printf '%s %4.2f %4.2f %4.2f %4.2f %4.2f %4.2f\n' \ + "${v}" "${!vr}" "${sum}" + done +} + +export LC_ALL=C + +get_times 1 cutting +get_times 10 cutting_versionator +get_times 1 replacing +get_times 10 replacing_versionator