<pman>Intégration de la branche rel74-0.5.1
This commit is contained in:
commit
8094346358
15
CHANGES.md
15
CHANGES.md
@ -1,3 +1,18 @@
|
||||
## Release 0.5.1p74 du 12/05/2025-15:28
|
||||
|
||||
* `d274a65` améliorer status
|
||||
* `2e026da` l'option -ww affiche la différence
|
||||
* `8e7e59c` intégrer les méthodes de Cursor et KeyAccess
|
||||
* `a587f99` installer completion pour pman
|
||||
* `cc56dc9` renommer pdev en pmer
|
||||
* `0a73ba3` améliorer ergonomie de p
|
||||
* `aef0533` ajout str::split
|
||||
* `87e262c` ajout cl::delv
|
||||
* `a371a68` maj doc
|
||||
* `d706122` ajout infos release
|
||||
|
||||
## Release 0.5.0p82 du 30/04/2025-04:33
|
||||
|
||||
## Release 0.5.0p74 du 30/04/2025-04:31
|
||||
|
||||
* `3ee92ef` ajout str::replace
|
||||
|
28
README.md
Normal file
28
README.md
Normal file
@ -0,0 +1,28 @@
|
||||
# nulib
|
||||
|
||||
|
||||
## Release
|
||||
|
||||
Exemple: release de la version 0.6.0
|
||||
~~~sh
|
||||
version=0.6.0
|
||||
|
||||
## branche dev74
|
||||
git checkout dev74
|
||||
|
||||
prel -v$version
|
||||
|
||||
_merge82
|
||||
|
||||
## branche dev82
|
||||
git checkout dev82
|
||||
|
||||
prel -C
|
||||
|
||||
commit="$(git log --grep="Init changelog . version ${version}p82" --format=%H)"
|
||||
git checkout dev74
|
||||
git cherry-pick "$commit"
|
||||
pp -a
|
||||
~~~
|
||||
|
||||
-*- coding: utf-8 mode: markdown -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8:noeol:binary
|
@ -1 +1 @@
|
||||
0.5.0
|
||||
0.5.1
|
||||
|
@ -84,6 +84,12 @@ function _list_commits() {
|
||||
_filter_rel
|
||||
}
|
||||
|
||||
function _show_diff() {
|
||||
local source="${1:-$SrcBranch}" dest="${2:-$DestBranch}" mergebase
|
||||
setx mergebase=git merge-base "$dest" "$source"
|
||||
git diff ${_sd_COLOR:+--color=$_sd_COLOR} "$mergebase..$source"
|
||||
}
|
||||
|
||||
function _scripte() {
|
||||
echo >>"$script"
|
||||
echo "$comment$(qvals "$@")" >>"$script"
|
||||
|
@ -1,4 +1,4 @@
|
||||
#!/bin/bash
|
||||
# -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
|
||||
|
||||
exec "$(dirname -- "$0")/pdev" --tech-merge -Bdev82 dev74 -a "git checkout dev74" "$@"
|
||||
exec "$(dirname -- "$0")/pmer" --tech-merge -Bdev82 dev74 -a "git checkout dev74" "$@"
|
||||
|
10
bin/p
10
bin/p
@ -29,6 +29,9 @@ function git_statuses() {
|
||||
done
|
||||
}
|
||||
|
||||
# sans arguments, il y a un comportement spécial
|
||||
[ $# -eq 0 ] && NoArgs=1 || NoArgs=
|
||||
|
||||
chdir=
|
||||
all=
|
||||
composer=
|
||||
@ -43,6 +46,13 @@ Si l'option -a est utilisée, ce script accepte comme arguments une liste de pat
|
||||
)
|
||||
parse_args "$@"; set -- "${args[@]}"
|
||||
|
||||
if [ -n "$NoArgs" ]; then
|
||||
# si aucun argument n'est spécifié et si on n'est pas dans un projet git,
|
||||
# afficher le status de tous les sous répertoires
|
||||
setx toplevel=git_get_toplevel
|
||||
[ -z "$toplevel" ] && all=1
|
||||
fi
|
||||
|
||||
setx OrigCwd=pwd
|
||||
if [ -n "$chdir" ]; then
|
||||
cd "$chdir" || die
|
||||
|
2
bin/pman
2
bin/pman
@ -78,7 +78,7 @@ function init_repo_action() {
|
||||
}
|
||||
|
||||
function init_config_action() {
|
||||
local -a push_branches; config
|
||||
local -a push_branches; local config
|
||||
|
||||
[ -f .pman.conf -a -z "$ForceCreate" ] && die "La configuration pman a déjà été initialisée"
|
||||
|
||||
|
@ -11,8 +11,19 @@ function show_action() {
|
||||
local commits
|
||||
setx commits=_list_commits
|
||||
if [ -n "$commits" ]; then
|
||||
einfo "Commits à fusionner $SrcBranch --> $DestBranch"
|
||||
eecho "$commits"
|
||||
if [ $ShowLevel -ge 2 ]; then
|
||||
{
|
||||
echo "\
|
||||
# Commits à fusionner $SrcBranch --> $DestBranch
|
||||
|
||||
$commits
|
||||
"
|
||||
_sd_COLOR=always _show_diff
|
||||
} | less -eRF
|
||||
else
|
||||
einfo "Commits à fusionner $SrcBranch --> $DestBranch"
|
||||
eecho "$commits"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
@ -148,6 +159,7 @@ ConfigFile=
|
||||
_Fake=
|
||||
_KeepScript=
|
||||
action=merge
|
||||
ShowLevel=0
|
||||
TechMerge=
|
||||
SquashMsg=
|
||||
[ -z "$PMAN_NO_PUSH" ] && Push=1 || Push=
|
||||
@ -158,6 +170,7 @@ args=(
|
||||
" [source]
|
||||
|
||||
CONFIGURATION
|
||||
|
||||
Le fichier .pman.conf contient la configuration des branches. Les variables
|
||||
supplémentaires suivantes peuvent être définies:
|
||||
BEFORE_MERGE_<srcType>
|
||||
@ -176,7 +189,7 @@ fichier de configuration des branches. cette option est prioritaire sur --config
|
||||
par défaut, utiliser le fichier .pman.conf dans le répertoire du dépôt s'il existe"
|
||||
--fake _Fake=1 "++option non documentée"
|
||||
--keep-script _KeepScript=1 "++option non documentée"
|
||||
-w,--show action=show "\
|
||||
-w,--show '$action=show; inc@ ShowLevel' "\
|
||||
lister les modifications qui seraient fusionnées dans la branche destination"
|
||||
-b,--rebase action=rebase "\
|
||||
lancer git rebase -i sur la branche source. cela permet de réordonner les
|
18
bin/prel
18
bin/prel
@ -11,8 +11,19 @@ function show_action() {
|
||||
local commits
|
||||
setx commits=_list_commits
|
||||
if [ -n "$commits" ]; then
|
||||
einfo "Commits à fusionner $SrcBranch --> $DestBranch"
|
||||
eecho "$commits"
|
||||
if [ $ShowLevel -ge 2 ]; then
|
||||
{
|
||||
echo "\
|
||||
# Commits à fusionner $SrcBranch --> $DestBranch
|
||||
|
||||
$commits
|
||||
"
|
||||
_sd_COLOR=always _show_diff
|
||||
} | less -eRF
|
||||
else
|
||||
einfo "Commits à fusionner $SrcBranch --> $DestBranch"
|
||||
eecho "$commits"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
@ -194,6 +205,7 @@ ConfigFile=
|
||||
_Fake=
|
||||
_KeepScript=
|
||||
action=release
|
||||
ShowLevel=0
|
||||
[ -z "$PMAN_NO_MERGE" ] && Merge=1 || Merge=
|
||||
[ -z "$PMAN_NO_PUSH" ] && Push=1 || Push=
|
||||
Version=
|
||||
@ -222,7 +234,7 @@ fichier de configuration des branches. cette option est prioritaire sur --config
|
||||
par défaut, utiliser le fichier .pman.conf dans le répertoire du dépôt s'il existe"
|
||||
--fake _Fake=1 "++option non documentée"
|
||||
--keep-script _KeepScript=1 "++option non documentée"
|
||||
-w,--show action=show "\
|
||||
-w,--show '$action=show; inc@ ShowLevel' "\
|
||||
lister les modifications qui seraient intégrées dans la release"
|
||||
--release action=release "++\
|
||||
créer la release.
|
||||
|
@ -29,7 +29,7 @@ for file in "$@"; do
|
||||
estep "Création de $file"
|
||||
|
||||
cat >"$file" <<EOF
|
||||
-- -*- coding: utf-8 mode: sql -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=$encoding
|
||||
-- -*- coding: utf-8 mode: sql -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
|
||||
-- @database xxx
|
||||
|
||||
start transaction;
|
||||
|
@ -1,6 +1,6 @@
|
||||
# -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
|
||||
|
||||
function __pman_pdev_branches() {
|
||||
function __pman_pmer_branches() {
|
||||
local toplevel="$(git rev-parse --show-toplevel 2>/dev/null)"
|
||||
[ -n "$toplevel" ] || return 0
|
||||
|
||||
@ -29,9 +29,9 @@ function __pman_pdev_branches() {
|
||||
)
|
||||
}
|
||||
|
||||
function __pdev_completion() {
|
||||
function __pmer_completion() {
|
||||
local cur
|
||||
_get_comp_words_by_ref cur
|
||||
COMPREPLY=($(compgen -W "$(__pman_pdev_branches)" "$cur"))
|
||||
COMPREPLY=($(compgen -W "$(__pman_pmer_branches)" "$cur"))
|
||||
}
|
||||
complete -F __pdev_completion pdev
|
||||
complete -F __pmer_completion pmer
|
||||
|
@ -1,6 +1,20 @@
|
||||
# -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
|
||||
|
||||
source "$@" || exit 1
|
||||
cd "$srcdir"
|
||||
|
||||
# supprimer les fichiers de VCS
|
||||
rm -rf "$srcdir/.git"
|
||||
rm -rf .git
|
||||
|
||||
# completion
|
||||
fromdir=lib/completion.d
|
||||
todir="$HOME/etc/completion.d"
|
||||
mkdir -p "$todir"
|
||||
for file in pman; do
|
||||
from="$fromdir/$file"
|
||||
to="$todir/$file"
|
||||
if [ -f "$to" ]; then
|
||||
diff -q "$from" "$to" && continue
|
||||
fi
|
||||
cp "$from" "$to"
|
||||
done
|
||||
|
112
php/src/A.php
112
php/src/A.php
@ -1,13 +1,14 @@
|
||||
<?php
|
||||
namespace nulib;
|
||||
|
||||
use nulib\php\func;
|
||||
use Traversable;
|
||||
|
||||
/**
|
||||
* Class A: gestion de tableaux ou d'instances de {@link IArrayWrapper}
|
||||
*
|
||||
* contrairement à {@link cl}, les méthodes de cette classes sont plutôt conçues
|
||||
* pour modifier le tableau en place
|
||||
* cette classe reprend les méthodes de {@link cl} avec la différence que la
|
||||
* modification est faite en place
|
||||
*/
|
||||
class A {
|
||||
/**
|
||||
@ -232,4 +233,111 @@ class A {
|
||||
if ($assoc) uasort($array, cl::compare($keys));
|
||||
else usort($array, cl::compare($keys));
|
||||
}
|
||||
|
||||
#############################################################################
|
||||
|
||||
/**
|
||||
* s'assurer que $array est un tableau associatif, en remplaçant toutes les
|
||||
* clés numériques par la clé correspondante dans $key
|
||||
* <code>
|
||||
* $array = ["first", "second"]
|
||||
* A::ensure_assoc($array, ["a", "b"]);
|
||||
* // returns ["a" => "first", "b" => "second"]
|
||||
* </code>
|
||||
*/
|
||||
static final function ensure_assoc(?array &$array, array $keys, ?array $params=null): void {
|
||||
$prefix = $params["key_prefix"] ?? null;
|
||||
$suffix = $params["key_suffix"] ?? null;
|
||||
$index = 0;
|
||||
foreach ($keys as $key) {
|
||||
if ($prefix !== null || $suffix !== null) {
|
||||
$destKey = "$prefix$key$suffix";
|
||||
} else {
|
||||
# préserver les clés numériques
|
||||
$destKey = $key;
|
||||
}
|
||||
if ($array !== null && array_key_exists($destKey, $array)) continue;
|
||||
while (in_array($index, $keys, true)) {
|
||||
$index++;
|
||||
}
|
||||
if ($array !== null && array_key_exists($index, $array)) {
|
||||
$array[$destKey] = $array[$index];
|
||||
unset($array[$index]);
|
||||
$index++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* s'assurer que $array contient toutes les clés de $defaults, avec la valeur
|
||||
* par défaut le cas échéant
|
||||
*
|
||||
* $missings est un tableau indiquant des valeurs qui si elles sont dans
|
||||
* $array, signifie que la clé correspondante doit être considérée comme
|
||||
* inexistante (et donc remplacée par la valeur de $defaults)
|
||||
*/
|
||||
static final function ensure_keys(?array &$array, array $defaults, ?array $missings=null, ?array $params=null): void {
|
||||
$keys = array_keys($defaults);
|
||||
$prefix = $params["key_prefix"] ?? null;
|
||||
$suffix = $params["key_suffix"] ?? null;
|
||||
foreach ($keys as $key) {
|
||||
$destKey = "$prefix$key$suffix";
|
||||
$haveMissing = $missings !== null && array_key_exists($key, $missings);
|
||||
if ($array === null || !array_key_exists($destKey, $array)) {
|
||||
$array[$destKey] = $defaults[$key];
|
||||
} elseif ($haveMissing && $array[$destKey] === $missings[$key]) {
|
||||
$array[$destKey] = $defaults[$key];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* supprimer dans $array les clés dont les valeurs correspondent au tableau
|
||||
* $missings
|
||||
*/
|
||||
static final function delete_missings(?array &$array, array $missings, ?array $params=null): void {
|
||||
$prefix = $params["key_prefix"] ?? null;
|
||||
$suffix = $params["key_suffix"] ?? null;
|
||||
foreach ($missings as $key => $missing) {
|
||||
$destKey = "$prefix$key$suffix";
|
||||
if (array_key_exists($destKey, $array) && $array[$destKey] === $missing) {
|
||||
unset($array[$destKey]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* s'assurer que les clés dans $array sont dans le même ordre que dans $keys
|
||||
*
|
||||
* les clés supplémentaires sont poussées à la fin du tableau
|
||||
*/
|
||||
static final function ensure_order(?array &$array, array $keys, ?array $params=null): void {
|
||||
if ($array === null) return;
|
||||
|
||||
$prefix = $params["key_prefix"] ?? null;
|
||||
$suffix = $params["key_suffix"] ?? null;
|
||||
if ($prefix !== null || $suffix !== null) {
|
||||
foreach ($keys as &$key) {
|
||||
$key = "$prefix$key$suffix";
|
||||
}; unset($key);
|
||||
}
|
||||
|
||||
$destKeys = array_keys($array);
|
||||
$keyCount = count($keys);
|
||||
if (array_slice($destKeys, 0, $keyCount) === $keys) {
|
||||
# si le tableau a déjà les bonnes clés dans le bon ordre, rien à faire
|
||||
return;
|
||||
}
|
||||
|
||||
$ordered = [];
|
||||
foreach ($keys as $key) {
|
||||
if (array_key_exists($key, $array)) {
|
||||
$ordered[$key] = $array[$key];
|
||||
unset($array[$key]);
|
||||
}
|
||||
}
|
||||
$preserveKeys = $params["preserve_keys"] ?? false;
|
||||
if ($preserveKeys) $array = cl::merge2($ordered, $array);
|
||||
else $array = array_merge($ordered, $array);
|
||||
}
|
||||
}
|
||||
|
@ -460,7 +460,7 @@ class RunFile {
|
||||
$exitcode = null;
|
||||
$message = [
|
||||
"status" => "$desc: EN COURS pid $data[pid]",
|
||||
"started" => "Démarrée depuis $dateStart ($sinceStart)",
|
||||
"started" => "Démarrée $sinceStart le $dateStart",
|
||||
"action" => $action,
|
||||
];
|
||||
} elseif ($this->isStopped($data)) {
|
||||
@ -471,8 +471,9 @@ class RunFile {
|
||||
elseif ($exitcode === 0) $type = "success";
|
||||
else $type = "danger";
|
||||
$message = [
|
||||
"status" => "$desc: TERMINEE$duration",
|
||||
"status" => "$desc: TERMINEE",
|
||||
"stopped" => "Arrêtée $sinceStop le $dateStop",
|
||||
"duration" => $duration,
|
||||
"result" => $result,
|
||||
];
|
||||
} else {
|
||||
|
139
php/src/cl.php
139
php/src/cl.php
@ -60,6 +60,35 @@ class cl {
|
||||
return $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* retourner la valeur à l'index $index, ou $default si le tableau est null
|
||||
* ou vide, ou si l'index n'existe pas
|
||||
*
|
||||
* ici, l'index est le rang de la clé: 0 pour la première clé du tableau, 1
|
||||
* pour la deuxième, etc.
|
||||
*
|
||||
* si $index est négatif, il est compté à partir de la fin du tableau
|
||||
*/
|
||||
static final function nth(?iterable $iterable, int $index, $default=null) {
|
||||
if ($iterable === null) return $default;
|
||||
if ($index < 0 && !is_array($iterable)) {
|
||||
$iterable = iterator_to_array($iterable, false);
|
||||
}
|
||||
if (is_array($iterable)) {
|
||||
$keys = array_keys($iterable);
|
||||
$count = count($keys);
|
||||
while ($index < 0) $index += $count;
|
||||
$key = $keys[$index] ?? null;
|
||||
if ($key === null) return $default;
|
||||
return $iterable[$key];
|
||||
}
|
||||
foreach ($iterable as $value) {
|
||||
if ($index === 0) return $value;
|
||||
$index--;
|
||||
}
|
||||
return $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* retourner la dernière valeur de $array ou $default si le tableau est null
|
||||
* ou vide
|
||||
@ -212,7 +241,7 @@ class cl {
|
||||
}
|
||||
|
||||
/**
|
||||
* obtenir la liste des clés finalement obtenues après l'appel à
|
||||
* obtenir la liste des clés qui seraient finalement obtenues après l'appel à
|
||||
* {@link self::select()} avec le mapping spécifié
|
||||
*/
|
||||
static final function selected_keys(?array $mappings): array {
|
||||
@ -255,7 +284,7 @@ class cl {
|
||||
* $includes qui ne sont pas mentionnées dans $excludes.
|
||||
*
|
||||
* - si $includes===null && $excludes===null, retourner le tableau inchangé
|
||||
* - si $includes vaut null, prendre toutes les clés
|
||||
* - si $includes vaut null, c'est comme si toutes les clés étaient incluses
|
||||
*
|
||||
*/
|
||||
static final function xselect($array, ?array $includes, ?array $excludes=null): ?array {
|
||||
@ -302,6 +331,27 @@ class cl {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* si $array est un array ou une instance de ArrayAccess&Traversable,
|
||||
* supprimer le premier élément dont la valeur est $value
|
||||
*
|
||||
* @param array|ArrayAccess $array
|
||||
*/
|
||||
static final function delv(&$array, $value, bool $strict=false): void {
|
||||
if (is_array($array)) {
|
||||
$key = array_search($value, $array, $strict);
|
||||
if ($key !== false) unset($array[$key]);
|
||||
} elseif ($array instanceof ArrayAccess && $array instanceof Traversable) {
|
||||
$found = false;
|
||||
foreach ($array as $key => $val) {
|
||||
if ($strict) $found = $val === $value;
|
||||
else $found = $val == $value;
|
||||
if ($found) break;
|
||||
}
|
||||
if ($found) $array->offsetUnset($key);
|
||||
}
|
||||
}
|
||||
|
||||
/** retourner le nombre d'éléments de $array */
|
||||
static final function count(?array $array): int {
|
||||
return $array !== null? count($array): 0;
|
||||
@ -348,15 +398,86 @@ class cl {
|
||||
|
||||
#############################################################################
|
||||
|
||||
static final function map($func, ?iterable $array): array {
|
||||
$result = [];
|
||||
if ($array !== null) {
|
||||
$func = func::with($func);
|
||||
foreach ($array as $key => $value) {
|
||||
$result[$key] = $func->invoke([$value, $key]);
|
||||
/**
|
||||
* tester si $array satisfait les conditions de $filter
|
||||
* - $filter est un scalaire, le transformer en [$filter]
|
||||
* - sinon $filter doit être un tableau de scalaires
|
||||
*
|
||||
* les règles des conditions sont les suivantes:
|
||||
* - une valeur séquentielle $key est équivalente à la valeur associative
|
||||
* $key => true
|
||||
* - une valeur associative $key => bool indique que la clé correspondante ne
|
||||
* doit pas (resp. doit) exister selon que bool vaut false (resp. true)
|
||||
* - une valeur associative $key => $value indique que la clé correspondante
|
||||
* doit exiter avec la valeur spécifiée
|
||||
*/
|
||||
static final function filter(?array $array, $filter): bool {
|
||||
if ($filter === null) return false;
|
||||
if (!is_array($filter)) $filter = [$filter];
|
||||
if (!$filter) return false;
|
||||
|
||||
$index = 0;
|
||||
foreach ($filter as $key => $value) {
|
||||
if ($key === $index) {
|
||||
$index++;
|
||||
if ($array === null) return false;
|
||||
if (!array_key_exists($value, $array)) return false;
|
||||
} elseif (is_bool($value)) {
|
||||
if ($value) {
|
||||
if ($array === null || !array_key_exists($key, $array)) return false;
|
||||
} else {
|
||||
if ($array !== null && array_key_exists($key, $array)) return false;
|
||||
}
|
||||
} else {
|
||||
if ($array === null) return false;
|
||||
if (!array_key_exists($key, $array)) return false;
|
||||
if ($array[$key] !== $value) return false;
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* mapper le tableau source $array selon les règles suivantes illustrées dans
|
||||
* l'exemple suivant:
|
||||
* si
|
||||
* $map = ["a", "b" => "x", "c" => function() { return "y"; }, "d" => null]
|
||||
* alors retourner le tableau
|
||||
* ["a" => $array["a"], "b" => $array["x"], "c" => "y", "d" => null]
|
||||
*
|
||||
* si une fonction est utilisée, sa signature est
|
||||
* <code>function(mixed $value, string|int $key, ?array $array)</code>
|
||||
*/
|
||||
static function map(?array $array, ?array $map): ?array {
|
||||
if ($map === null) return $array;
|
||||
$index = 0;
|
||||
$mapped = [];
|
||||
foreach ($map as $key => $value) {
|
||||
if ($key === $index) {
|
||||
$index++;
|
||||
if ($value === null) $mapped[] = null;
|
||||
else $mapped[$value] = cl::get($array, $value);
|
||||
} elseif (is_callable($value)) {
|
||||
$func = func::with($value);
|
||||
$value = cl::get($array, $key);
|
||||
$mapped[$key] = $func->invoke([$value, $key, $array]);
|
||||
} else {
|
||||
if ($value === null) $mapped[$key] = null;
|
||||
else $mapped[$key] = cl::get($array, $value);
|
||||
}
|
||||
}
|
||||
return $mapped;
|
||||
}
|
||||
|
||||
static final function mapf(?iterable $items, $func): array {
|
||||
$mapped = [];
|
||||
if ($items !== null) {
|
||||
$func = func::with($func);
|
||||
foreach ($items as $key => $item) {
|
||||
$mapped[$key] = $func->invoke([$item, $key, $items]);
|
||||
}
|
||||
}
|
||||
return $mapped;
|
||||
}
|
||||
|
||||
#############################################################################
|
||||
|
@ -677,7 +677,7 @@ abstract class CapacitorStorage {
|
||||
function _delete(CapacitorChannel $channel, $filter, $func, ?array $args): int {
|
||||
$this->_create($channel);
|
||||
if ($func === null) $func = CapacitorChannel::onDelete;
|
||||
$onEach = func::with($func)->bind($channel);
|
||||
$onDelete = func::with($func)->bind($channel);
|
||||
$db = $this->db();
|
||||
# si on est déjà dans une transaction, désactiver la gestion des transactions
|
||||
$manageTransactions = $channel->isManageTransactions() && !$db->inTransaction();
|
||||
@ -693,8 +693,8 @@ abstract class CapacitorStorage {
|
||||
$all = $this->_allCached("delete", $channel, $filter);
|
||||
foreach ($all as $values) {
|
||||
$rowIds = $this->getRowIds($channel, $values);
|
||||
$delete = boolval($onEach->invoke([$values["item"], $values, ...$args]));
|
||||
if ($delete) {
|
||||
$shouldDelete = boolval($onDelete->invoke([$values["item"], $values, ...$args]));
|
||||
if ($shouldDelete) {
|
||||
$db->exec([
|
||||
"delete",
|
||||
"from" => $tableName,
|
||||
|
@ -23,7 +23,8 @@ class _select extends _common {
|
||||
return preg_match("/^select\b/i", $sql);
|
||||
}
|
||||
|
||||
private static function add_prefix(string $col, ?string $prefix): string {
|
||||
private static function add_prefix(?string $col, ?string $prefix): string {
|
||||
$col ??= "null";
|
||||
if ($prefix === null) return $col;
|
||||
if (strpos($col, ".") !== false) return $col;
|
||||
return "$prefix$col";
|
||||
|
@ -81,6 +81,12 @@ class Pgsql implements IDatabase {
|
||||
#if ($tmp !== null) $dbconn = $tmp;
|
||||
#else $dbconn = ["" => $dbconn];
|
||||
}
|
||||
unset($dbconn["type"]);
|
||||
$name = $dbconn["name"] ?? null;
|
||||
if ($name !== null) {
|
||||
$dbconn[""] = $name;
|
||||
unset($dbconn["name"]);
|
||||
}
|
||||
$params["dbconn"] = $dbconn;
|
||||
}
|
||||
# dbconn
|
||||
|
@ -40,12 +40,20 @@ class SqliteStorage extends CapacitorStorage {
|
||||
return new _sqliteMigration($migrations, $channel->getName());
|
||||
}
|
||||
|
||||
function channelExists(string $name): bool {
|
||||
return null !== $this->db->get([
|
||||
"select name",
|
||||
function channelExists(string $name, ?array &$row=null): bool {
|
||||
$row = $this->db->one([
|
||||
"select",
|
||||
"from" => static::CHANNELS_TABLE,
|
||||
"where" => ["name" => $name],
|
||||
]);
|
||||
return $row !== null;
|
||||
}
|
||||
|
||||
function getChannels(): iterable {
|
||||
return $this->db->all([
|
||||
"select",
|
||||
"from" => static::CHANNELS_TABLE,
|
||||
]);
|
||||
}
|
||||
|
||||
protected function _addToChannelsSql(CapacitorChannel $channel): array {
|
||||
|
@ -59,9 +59,10 @@ class func {
|
||||
* @param bool $strict vérifier l'inexistence de la classe et l'existence de
|
||||
* la fonction (ne pas uniquement faire une vérification syntaxique)
|
||||
*/
|
||||
static function verifix_function(&$func, bool $strict=true, ?string &$reason=null): bool {
|
||||
static function verifix_function(&$func, ?array &$args=null, bool $strict=true, ?string &$reason=null): bool {
|
||||
if ($strict) $reason = null;
|
||||
if ($func instanceof ReflectionFunction) return true;
|
||||
$rargs = null;
|
||||
if (is_string($func)) {
|
||||
$c = false;
|
||||
$f = $func;
|
||||
@ -70,6 +71,7 @@ class func {
|
||||
$c = $func[0];
|
||||
if (!array_key_exists(1, $func)) return false;
|
||||
$f = $func[1];
|
||||
$rargs = array_slice($func, 2);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
@ -90,6 +92,7 @@ class func {
|
||||
}
|
||||
}
|
||||
$func = [false, $f];
|
||||
if ($rargs) $args = cl::merge($rargs, $args);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -98,7 +101,7 @@ class func {
|
||||
* {@link self::verifix_function()}
|
||||
*/
|
||||
static function is_function($func, bool $strict=true, ?string &$reason=null): bool {
|
||||
return self::verifix_function($func, $strict, $reason);
|
||||
return self::verifix_function($func, $args, $strict, $reason);
|
||||
}
|
||||
|
||||
#############################################################################
|
||||
@ -115,9 +118,10 @@ class func {
|
||||
* @param bool $strict vérifier l'existence de la classe (ne pas uniquement
|
||||
* faire une vérification syntaxique)
|
||||
*/
|
||||
static function verifix_class(&$func, bool $strict=true, ?string &$reason=null): bool {
|
||||
static function verifix_class(&$func, ?array &$args=null, bool $strict=true, ?string &$reason=null): bool {
|
||||
if ($strict) $reason = null;
|
||||
if ($func instanceof ReflectionClass) return true;
|
||||
$rargs = null;
|
||||
if (is_string($func)) {
|
||||
$c = $func;
|
||||
$f = false;
|
||||
@ -126,6 +130,7 @@ class func {
|
||||
$c = $func[0];
|
||||
if (!array_key_exists(1, $func)) return false;
|
||||
$f = $func[1];
|
||||
$rargs = array_slice($func, 2);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
@ -139,6 +144,7 @@ class func {
|
||||
return false;
|
||||
}
|
||||
$func = [$c, false];
|
||||
if ($rargs) $args = cl::merge($rargs, $args);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -147,7 +153,7 @@ class func {
|
||||
* {@link self::verifix_class()}
|
||||
*/
|
||||
static function is_class($func, bool $strict=true, ?string &$reason=null): bool {
|
||||
return self::verifix_class($func, $strict, $reason);
|
||||
return self::verifix_class($func, $args, $strict, $reason);
|
||||
}
|
||||
|
||||
#############################################################################
|
||||
@ -198,14 +204,16 @@ class func {
|
||||
* liée à une classe avant d'être utilisée
|
||||
*
|
||||
* @param bool $strict vérifier l'existence de la classe et de la méthode si
|
||||
* @param array|null &$args
|
||||
* la méthode est liée (ne pas uniquement faire une vérification syntaxique)
|
||||
*/
|
||||
static function verifix_static(&$func, bool $strict=true, ?bool &$bound=null, ?string &$reason=null): bool {
|
||||
static function verifix_static(&$func, ?array &$args = null, bool $strict=true, ?bool &$bound=null, ?string &$reason=null): bool {
|
||||
if ($strict) $reason = null;
|
||||
if ($func instanceof ReflectionMethod) {
|
||||
$bound = false;
|
||||
return true;
|
||||
}
|
||||
$rargs = null;
|
||||
if (is_string($func)) {
|
||||
if (!self::_parse_c_static($func, $c, $f, $bound)) return false;
|
||||
$cf = [$c, $f];
|
||||
@ -252,6 +260,7 @@ class func {
|
||||
self::_parse_static($f);
|
||||
}
|
||||
$cf[1] = $f;
|
||||
$rargs = array_slice($func, 2);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
@ -274,6 +283,7 @@ class func {
|
||||
}
|
||||
}
|
||||
$func = $cf;
|
||||
if ($rargs) $args = cl::merge($rargs, $args);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -282,7 +292,7 @@ class func {
|
||||
* {@link self::verifix_static()}
|
||||
*/
|
||||
static function is_static($func, bool $strict=true, ?bool &$bound=null, ?string &$reason=null): bool {
|
||||
return self::verifix_static($func, $strict, $bound, $reason);
|
||||
return self::verifix_static($func, $args, $strict, $bound, $reason);
|
||||
}
|
||||
|
||||
#############################################################################
|
||||
@ -335,12 +345,13 @@ class func {
|
||||
* @param bool $strict vérifier l'existence de la classe et de la méthode si
|
||||
* la méthode est liée (ne pas uniquement faire une vérification syntaxique)
|
||||
*/
|
||||
static function verifix_method(&$func, bool $strict=true, ?bool &$bound=null, ?string &$reason=null): bool {
|
||||
static function verifix_method(&$func, ?array &$args=null, bool $strict=true, ?bool &$bound=null, ?string &$reason=null): bool {
|
||||
if ($strict) $reason = null;
|
||||
if ($func instanceof ReflectionMethod) {
|
||||
$bound = false;
|
||||
return true;
|
||||
}
|
||||
$rargs = null;
|
||||
if (is_string($func)) {
|
||||
if (!self::_parse_c_method($func, $c, $f, $bound)) return false;
|
||||
$cf = [$c, $f];
|
||||
@ -388,6 +399,7 @@ class func {
|
||||
self::_parse_method($f);
|
||||
}
|
||||
$cf[1] = $f;
|
||||
$rargs = array_slice($func, 2);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
@ -410,6 +422,7 @@ class func {
|
||||
}
|
||||
}
|
||||
$func = $cf;
|
||||
if ($rargs) $args = cl::merge($rargs, $args);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -418,7 +431,7 @@ class func {
|
||||
* {@link self::verifix_method()}
|
||||
*/
|
||||
static function is_method($func, bool $strict=true, ?bool &$bound=null, ?string &$reason=null): bool {
|
||||
return self::verifix_method($func, $strict, $bound, $reason);
|
||||
return self::verifix_method($func, $args, $strict, $bound, $reason);
|
||||
}
|
||||
|
||||
#############################################################################
|
||||
@ -452,13 +465,13 @@ class func {
|
||||
return new self(self::TYPE_METHOD, $func, $args, false);
|
||||
}
|
||||
}
|
||||
if (self::verifix_function($func, $strict, $reason)) {
|
||||
if (self::verifix_function($func, $args, $strict, $reason)) {
|
||||
return new self(self::TYPE_FUNCTION, $func, $args, false, $reason);
|
||||
} elseif (self::verifix_class($func, $strict, $reason)) {
|
||||
} elseif (self::verifix_class($func, $args, $strict, $reason)) {
|
||||
return new self(self::TYPE_CLASS, $func, $args, false, $reason);
|
||||
} elseif (self::verifix_method($func, $strict, $bound, $reason)) {
|
||||
} elseif (self::verifix_method($func, $args, $strict, $bound, $reason)) {
|
||||
return new self(self::TYPE_METHOD, $func, $args, $bound, $reason);
|
||||
} elseif (self::verifix_static($func, $strict, $bound, $reason)) {
|
||||
} elseif (self::verifix_static($func, $args, $strict, $bound, $reason)) {
|
||||
return new self(self::TYPE_STATIC, $func, $args, $bound, $reason);
|
||||
}
|
||||
return null;
|
||||
|
@ -328,6 +328,22 @@ class str {
|
||||
else return preg_split('/\s+/', $s);
|
||||
}
|
||||
|
||||
/**
|
||||
* découper la chaine:
|
||||
* - avec preg_split si $sep est une expression régulière /re/
|
||||
* - avec explode sinon
|
||||
*/
|
||||
static final function split(string $sep, ?string $s): ?array {
|
||||
if ($s === null) return null;
|
||||
if ($sep === "") {
|
||||
return [$s];
|
||||
} elseif (substr($sep, 0, 1) === "/") {
|
||||
return preg_split($sep, $s);
|
||||
} else {
|
||||
return explode($sep, $s);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* joindre les éléments de $parts comme avec implode(), mais en ignorant les
|
||||
* valeurs fausses (cela n'inclue pas la chaine "0")
|
||||
|
@ -12,10 +12,10 @@ class clTest extends TestCase {
|
||||
}
|
||||
function test_same_keys() {
|
||||
$array = ["a" => 42, "b" => "tesxt"]; $arrayKeys = array_keys($array);
|
||||
$xarray = ["parasite0", "a" => 42, "parasite1", "b" => "tesxt"]; $xarrayKeys = array_keys($array);
|
||||
$missingArray = ["c" => true]; $missingArrayKeys = array_keys($missingArray);
|
||||
$ref = ["a" => "int", "b" => "text"]; $refKeys = array_keys($ref);
|
||||
$missingArray = ["c" => true]; $missingKeys = array_keys($missingArray);
|
||||
$missingRef = ["c" => "bool"]; $missingKeys = array_keys($missingRef);
|
||||
$missingRef = ["c" => "bool"]; $missingRefKeys = array_keys($missingRef);
|
||||
$xarray = ["parasite0", "a" => 42, "parasite1", "b" => "tesxt"];
|
||||
|
||||
$this->checkKeys(null, null, true, [], [], []);
|
||||
$this->checkKeys(null, [], true, [], [], []);
|
||||
@ -29,8 +29,8 @@ class clTest extends TestCase {
|
||||
$this->checkKeys($array, [], true, [], $arrayKeys, []);
|
||||
|
||||
$this->checkKeys($array, $ref, true, $arrayKeys, [], []);
|
||||
$this->checkKeys(cl::merge($array, $missingArray), $ref, true, $arrayKeys, $missingKeys, []);
|
||||
$this->checkKeys($array, cl::merge($ref, $missingRef), false, $arrayKeys, [], $missingKeys);
|
||||
$this->checkKeys(cl::merge($array, $missingArray), $ref, true, $arrayKeys, $missingArrayKeys, []);
|
||||
$this->checkKeys($array, cl::merge($ref, $missingRef), false, $arrayKeys, [], $missingRefKeys);
|
||||
|
||||
$this->checkKeys($xarray, $ref, false, $arrayKeys, [0, 1], []);
|
||||
}
|
||||
|
@ -295,14 +295,14 @@ namespace nulib\php {
|
||||
|
||||
$workf = $func;
|
||||
$msg = var_export($func, true)." (strict)";
|
||||
self::assertSame($verifix1, func::verifix_function($workf, true), "$msg --> verifix");
|
||||
self::assertSame($verifix1, func::verifix_function($workf, $args, true), "$msg --> verifix");
|
||||
if ($verifix1) {
|
||||
self::assertSame($func1, $workf, "$msg --> func");
|
||||
}
|
||||
|
||||
$workf = $func;
|
||||
$msg = var_export($func, true)." (lenient)";
|
||||
self::assertSame($verifix2, func::verifix_function($workf, false), "$msg --> verifix");
|
||||
self::assertSame($verifix2, func::verifix_function($workf, $args, false), "$msg --> verifix");
|
||||
if ($verifix2) {
|
||||
self::assertSame($func2, $workf, "$msg --> func");
|
||||
}
|
||||
@ -595,7 +595,7 @@ namespace nulib\php {
|
||||
|
||||
$workf = $func;
|
||||
$msg = var_export($func, true)." (strict)";
|
||||
self::assertSame($verifix1, func::verifix_static($workf, true, $bound), "$msg --> verifix");
|
||||
self::assertSame($verifix1, func::verifix_static($workf, $args, true, $bound), "$msg --> verifix");
|
||||
if ($verifix1) {
|
||||
self::assertSame($bound1, $bound, "$msg --> bound");
|
||||
self::assertSame($func1, $workf, "$msg --> func");
|
||||
@ -603,7 +603,7 @@ namespace nulib\php {
|
||||
|
||||
$workf = $func;
|
||||
$msg = var_export($func, true)." (lenient)";
|
||||
self::assertSame($verifix2, func::verifix_static($workf, false, $bound), "$msg --> verifix");
|
||||
self::assertSame($verifix2, func::verifix_static($workf, $args, false, $bound), "$msg --> verifix");
|
||||
if ($verifix2) {
|
||||
self::assertSame($bound2, $bound, "$msg --> bound");
|
||||
self::assertSame($func2, $workf, "$msg --> func");
|
||||
@ -894,7 +894,7 @@ namespace nulib\php {
|
||||
|
||||
$workf = $func;
|
||||
$msg = var_export($func, true)." (strict)";
|
||||
self::assertSame($verifix1, func::verifix_method($workf, true, $bound), "$msg --> verifix");
|
||||
self::assertSame($verifix1, func::verifix_method($workf, $args, true, $bound), "$msg --> verifix");
|
||||
if ($verifix1) {
|
||||
self::assertSame($bound1, $bound, "$msg --> bound");
|
||||
self::assertSame($func1, $workf, "$msg --> func");
|
||||
@ -902,7 +902,7 @@ namespace nulib\php {
|
||||
|
||||
$workf = $func;
|
||||
$msg = var_export($func, true)." (lenient)";
|
||||
self::assertSame($verifix2, func::verifix_method($workf, false, $bound), "$msg --> verifix");
|
||||
self::assertSame($verifix2, func::verifix_method($workf, $args, false, $bound), "$msg --> verifix");
|
||||
if ($verifix2) {
|
||||
self::assertSame($bound2, $bound, "$msg --> bound");
|
||||
self::assertSame($func2, $workf, "$msg --> func");
|
||||
|
@ -6,7 +6,7 @@ outil pour gérer les projets PHP
|
||||
projets dépendants du projet courant
|
||||
* pver: gestion des versions.
|
||||
calculer la prochaine version en respectant semver
|
||||
* pdev: gérer les branches de features et hotfixes.
|
||||
* pmer: gérer les branches de features et hotfixes.
|
||||
* prel: faire une release.
|
||||
ces outils peuvent agir sur les projets dépendants: faire une release sur un
|
||||
projet downstream, ou synchroniser la version depuis un projet upstream
|
||||
|
Loading…
x
Reference in New Issue
Block a user