<pman>Intégration de la branche rel74-0.4.0
This commit is contained in:
		
						commit
						559feda663
					
				
							
								
								
									
										8
									
								
								.pman.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								.pman.yml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,8 @@ | |||||||
|  | # -*- coding: utf-8 mode: yaml -*- vim:sw=2:sts=2:et:ai:si:sta:fenc=utf-8 | ||||||
|  | 
 | ||||||
|  | composer: | ||||||
|  |   profiles: [ dev, dist ] | ||||||
|  |   dev: | ||||||
|  |     link: true | ||||||
|  |   dist: | ||||||
|  |     link: false | ||||||
							
								
								
									
										33
									
								
								CHANGES.md
									
									
									
									
									
								
							
							
						
						
									
										33
									
								
								CHANGES.md
									
									
									
									
									
								
							| @ -1,9 +1,36 @@ | |||||||
|  | ## Release 0.4.0p74 du 14/03/2025-15:23 | ||||||
|  | 
 | ||||||
|  | * `cf9fab5` maj src/php | ||||||
|  | * `5c5d878` pdev: option --force-merge | ||||||
|  | * `9723c14` ajout cl::same_keys() | ||||||
|  | * `5ae3e8b` pdev: ajout --after-merge | ||||||
|  | * `cfc386d` Revert "prel/pdev: tracer les hooks" | ||||||
|  | * `d44537a` prel/pdev: tracer les hooks | ||||||
|  | * `e8abaca` supprimer tests qui sont encore dans nur/ture | ||||||
|  | * `a3116e5` ajout du schéma | ||||||
|  | * `0d2ca20` prel/pdev: option --fake | ||||||
|  | * `bd0da9c` prel/pdev: ajouter les hook BEFORE_* | ||||||
|  | * `7e05caf` runphp: passer les arguments inchangés à composer | ||||||
|  | * `9def939` p: support des projets dépendants composer | ||||||
|  | * `01c65a6` tests verbosity et interaction | ||||||
|  | * `8e3569a` ne plus utiliser tooenc par défaut. renommer tooenc en uecho | ||||||
|  | * `ead5b5a` support automatique options verbosity et interaction | ||||||
|  | * `8825493` pman: tenir compte des branches distantes | ||||||
|  | * `e129e0a` ajout pwip | ||||||
|  | * `9a2378b` pman: améliorer l'ergonomie | ||||||
|  | * `8cfd803` gestion des profils composer | ||||||
|  | * `d9989c6` supprimer composer.phar puisque c'est fourni par runphp | ||||||
|  | * `7eb5efb` ajout config .pman.yml | ||||||
|  | * `92363cd` pman: option --force-create | ||||||
|  | * `3b379eb` maj doc | ||||||
|  | * `bbb5559` pman: ajout init pman | ||||||
|  | * `939f772` pman: support des config standard nommées | ||||||
|  | 
 | ||||||
|  | ## Release 0.3.4p82 du 01/03/2025-06:23 | ||||||
|  | 
 | ||||||
| ## Release 0.3.4p74 du 01/03/2025-06:22 | ## Release 0.3.4p74 du 01/03/2025-06:22 | ||||||
| 
 | 
 | ||||||
| * `62b9230` pdev: ne pas inscrire delete si cette opération est interdite | * `62b9230` pdev: ne pas inscrire delete si cette opération est interdite | ||||||
| 
 |  | ||||||
| ## Release 0.3.3p74 du 01/03/2025-06:14 |  | ||||||
| 
 |  | ||||||
| * `2163ea9` pdev/prel: scripts post merge/release | * `2163ea9` pdev/prel: scripts post merge/release | ||||||
| 
 | 
 | ||||||
| ## Release 0.3.2p82 du 28/02/2025-20:30 | ## Release 0.3.2p82 du 28/02/2025-20:30 | ||||||
|  | |||||||
| @ -1 +1 @@ | |||||||
| 0.3.4 | 0.4.0 | ||||||
|  | |||||||
| @ -6,15 +6,15 @@ function __esection() { | |||||||
|     local length="${COLUMNS:-80}" |     local length="${COLUMNS:-80}" | ||||||
|     setx lsep=__complete "$prefix" "$length" - |     setx lsep=__complete "$prefix" "$length" - | ||||||
| 
 | 
 | ||||||
|     tooenc "$COULEUR_BLEUE$lsep$COULEUR_NORMALE" |     recho "$COULEUR_BLEUE$lsep$COULEUR_NORMALE" | ||||||
|     [ -n "$*" ] || return 0 |     [ -n "$*" ] || return 0 | ||||||
|     length=$((length - 1)) |     length=$((length - 1)) | ||||||
|     setx -a lines=echo "$1" |     setx -a lines=echo "$1" | ||||||
|     for line in "${lines[@]}"; do |     for line in "${lines[@]}"; do | ||||||
|         setx line=__complete "$prefix- $line" "$length" |         setx line=__complete "$prefix- $line" "$length" | ||||||
|         tooenc "$COULEUR_BLEUE$line-$COULEUR_NORMALE" |         recho "$COULEUR_BLEUE$line-$COULEUR_NORMALE" | ||||||
|     done |     done | ||||||
|     tooenc "$COULEUR_BLEUE$lsep$COULEUR_NORMALE" |     recho "$COULEUR_BLEUE$lsep$COULEUR_NORMALE" | ||||||
| } | } | ||||||
| function __etitle() { | function __etitle() { | ||||||
|     local -a lines; local maxlen=0 |     local -a lines; local maxlen=0 | ||||||
| @ -23,10 +23,10 @@ function __etitle() { | |||||||
|     setx -a lines=echo "$1" |     setx -a lines=echo "$1" | ||||||
|     for line in "${lines[@]}"; do |     for line in "${lines[@]}"; do | ||||||
|         [ ${#line} -gt $maxlen ] && maxlen=${#line} |         [ ${#line} -gt $maxlen ] && maxlen=${#line} | ||||||
|         tooenc "${prefix}${COULEUR_BLEUE}T $line$COULEUR_NORMALE" |         recho "${prefix}${COULEUR_BLEUE}T $line$COULEUR_NORMALE" | ||||||
|     done |     done | ||||||
|     maxlen=$((maxlen + 2)) |     maxlen=$((maxlen + 2)) | ||||||
|     tooenc "${prefix}${COULEUR_BLEUE}T$(__complete "" $maxlen -)${COULEUR_NORMALE}" |     recho "${prefix}${COULEUR_BLEUE}T$(__complete "" $maxlen -)${COULEUR_NORMALE}" | ||||||
| } | } | ||||||
| function __edesc() { | function __edesc() { | ||||||
|     local -a lines |     local -a lines | ||||||
| @ -34,7 +34,7 @@ function __edesc() { | |||||||
|      |      | ||||||
|     setx -a lines=echo "$1" |     setx -a lines=echo "$1" | ||||||
|     for line in "${lines[@]}"; do |     for line in "${lines[@]}"; do | ||||||
|         tooenc "${prefix}${COULEUR_BLEUE}>${COULEUR_NORMALE} $line" |         recho "${prefix}${COULEUR_BLEUE}>${COULEUR_NORMALE} $line" | ||||||
|     done |     done | ||||||
| } | } | ||||||
| function __ebanner() { | function __ebanner() { | ||||||
| @ -43,35 +43,35 @@ function __ebanner() { | |||||||
|     local length="${COLUMNS:-80}" |     local length="${COLUMNS:-80}" | ||||||
|     setx lsep=__complete "$prefix" "$length" = |     setx lsep=__complete "$prefix" "$length" = | ||||||
| 
 | 
 | ||||||
|     tooenc "$COULEUR_ROUGE$lsep" |     recho "$COULEUR_ROUGE$lsep" | ||||||
|     length=$((length - 1)) |     length=$((length - 1)) | ||||||
|     setx -a lines=echo "$1" |     setx -a lines=echo "$1" | ||||||
|     for line in "" "${lines[@]}" ""; do |     for line in "" "${lines[@]}" ""; do | ||||||
|         setx line=__complete "$prefix= $line" "$length" |         setx line=__complete "$prefix= $line" "$length" | ||||||
|         tooenc "$line=" |         recho "$line=" | ||||||
|     done |     done | ||||||
|     tooenc "$lsep$COULEUR_NORMALE" |     recho "$lsep$COULEUR_NORMALE" | ||||||
| } | } | ||||||
| function __eimportant() { tooenc "$(__edate)$(__eindent0)${COULEUR_ROUGE}!${COULEUR_NORMALE} $(__eindent "$1" "  ")"; } | function __eimportant() { recho "$(__edate)$(__eindent0)${COULEUR_ROUGE}!${COULEUR_NORMALE} $(__eindent "$1" "  ")"; } | ||||||
| function __eattention() { tooenc "$(__edate)$(__eindent0)${COULEUR_JAUNE}*${COULEUR_NORMALE} $(__eindent "$1" "  ")"; } | function __eattention() { recho "$(__edate)$(__eindent0)${COULEUR_JAUNE}*${COULEUR_NORMALE} $(__eindent "$1" "  ")"; } | ||||||
| function __eerror() { tooenc "$(__edate)$(__eindent0)${COULEUR_ROUGE}E${COULEUR_NORMALE} $(__eindent "$1" "  ")"; } | function __eerror() { recho "$(__edate)$(__eindent0)${COULEUR_ROUGE}E${COULEUR_NORMALE} $(__eindent "$1" "  ")"; } | ||||||
| function __ewarn() { tooenc "$(__edate)$(__eindent0)${COULEUR_JAUNE}W${COULEUR_NORMALE} $(__eindent "$1" "  ")"; } | function __ewarn() { recho "$(__edate)$(__eindent0)${COULEUR_JAUNE}W${COULEUR_NORMALE} $(__eindent "$1" "  ")"; } | ||||||
| function __enote() { tooenc "$(__edate)$(__eindent0)${COULEUR_VERTE}N${COULEUR_NORMALE} $(__eindent "$1" "  ")"; } | function __enote() { recho "$(__edate)$(__eindent0)${COULEUR_VERTE}N${COULEUR_NORMALE} $(__eindent "$1" "  ")"; } | ||||||
| function __einfo() { tooenc "$(__edate)$(__eindent0)${COULEUR_BLEUE}I${COULEUR_NORMALE} $(__eindent "$1" "  ")"; } | function __einfo() { recho "$(__edate)$(__eindent0)${COULEUR_BLEUE}I${COULEUR_NORMALE} $(__eindent "$1" "  ")"; } | ||||||
| function __edebug() { tooenc "$(__edate)$(__eindent0)${COULEUR_BLANCHE}D${COULEUR_NORMALE} $(__eindent "$1" "  ")"; } | function __edebug() { recho "$(__edate)$(__eindent0)${COULEUR_BLANCHE}D${COULEUR_NORMALE} $(__eindent "$1" "  ")"; } | ||||||
| 
 | 
 | ||||||
| function __estep() { tooenc "$(__edate)$(__eindent0)${COULEUR_BLANCHE}.${COULEUR_NORMALE} $(__eindent "$1" "  ")"; } | function __estep() { recho "$(__edate)$(__eindent0)${COULEUR_BLANCHE}.${COULEUR_NORMALE} $(__eindent "$1" "  ")"; } | ||||||
| function __estepe() { tooenc "$(__edate)$(__eindent0)${COULEUR_ROUGE}.${COULEUR_NORMALE} $(__eindent "$1" "  ")"; } | function __estepe() { recho "$(__edate)$(__eindent0)${COULEUR_ROUGE}.${COULEUR_NORMALE} $(__eindent "$1" "  ")"; } | ||||||
| function __estepw() { tooenc "$(__edate)$(__eindent0)${COULEUR_JAUNE}.${COULEUR_NORMALE} $(__eindent "$1" "  ")"; } | function __estepw() { recho "$(__edate)$(__eindent0)${COULEUR_JAUNE}.${COULEUR_NORMALE} $(__eindent "$1" "  ")"; } | ||||||
| function __estepn() { tooenc "$(__edate)$(__eindent0)${COULEUR_VERTE}.${COULEUR_NORMALE} $(__eindent "$1" "  ")"; } | function __estepn() { recho "$(__edate)$(__eindent0)${COULEUR_VERTE}.${COULEUR_NORMALE} $(__eindent "$1" "  ")"; } | ||||||
| function __estepi() { tooenc "$(__edate)$(__eindent0)${COULEUR_BLEUE}.${COULEUR_NORMALE} $(__eindent "$1" "  ")"; } | function __estepi() { recho "$(__edate)$(__eindent0)${COULEUR_BLEUE}.${COULEUR_NORMALE} $(__eindent "$1" "  ")"; } | ||||||
| function __estep_() { tooenc_ "$(__edate)$(__eindent0)${COULEUR_BLANCHE}.${COULEUR_NORMALE} $(__eindent "$1" "  ")"; } | function __estep_() { recho_ "$(__edate)$(__eindent0)${COULEUR_BLANCHE}.${COULEUR_NORMALE} $(__eindent "$1" "  ")"; } | ||||||
| function __estepe_() { tooenc_ "$(__edate)$(__eindent0)${COULEUR_ROUGE}.${COULEUR_NORMALE} $(__eindent "$1" "  ")"; } | function __estepe_() { recho_ "$(__edate)$(__eindent0)${COULEUR_ROUGE}.${COULEUR_NORMALE} $(__eindent "$1" "  ")"; } | ||||||
| function __estepw_() { tooenc_ "$(__edate)$(__eindent0)${COULEUR_JAUNE}.${COULEUR_NORMALE} $(__eindent "$1" "  ")"; } | function __estepw_() { recho_ "$(__edate)$(__eindent0)${COULEUR_JAUNE}.${COULEUR_NORMALE} $(__eindent "$1" "  ")"; } | ||||||
| function __estepn_() { tooenc_ "$(__edate)$(__eindent0)${COULEUR_VERTE}.${COULEUR_NORMALE} $(__eindent "$1" "  ")"; } | function __estepn_() { recho_ "$(__edate)$(__eindent0)${COULEUR_VERTE}.${COULEUR_NORMALE} $(__eindent "$1" "  ")"; } | ||||||
| function __estepi_() { tooenc_ "$(__edate)$(__eindent0)${COULEUR_BLEUE}.${COULEUR_NORMALE} $(__eindent "$1" "  ")"; } | function __estepi_() { recho_ "$(__edate)$(__eindent0)${COULEUR_BLEUE}.${COULEUR_NORMALE} $(__eindent "$1" "  ")"; } | ||||||
| 
 | 
 | ||||||
| function __action() { tooenc "$(__edate)$(__eindent0)${COULEUR_BLANCHE}.${COULEUR_NORMALE} $(__eindent "$1" "  ")"; } | function __action() { recho "$(__edate)$(__eindent0)${COULEUR_BLANCHE}.${COULEUR_NORMALE} $(__eindent "$1" "  ")"; } | ||||||
| function __asuccess() { tooenc "$(__edate)$(__eindent0)${COULEUR_VERTE}✔${COULEUR_NORMALE} $(__eindent "$1" "  ")"; } | function __asuccess() { recho "$(__edate)$(__eindent0)${COULEUR_VERTE}✔${COULEUR_NORMALE} $(__eindent "$1" "  ")"; } | ||||||
| function __afailure() { tooenc "$(__edate)$(__eindent0)${COULEUR_ROUGE}✘${COULEUR_NORMALE} $(__eindent "$1" "  ")"; } | function __afailure() { recho "$(__edate)$(__eindent0)${COULEUR_ROUGE}✘${COULEUR_NORMALE} $(__eindent "$1" "  ")"; } | ||||||
| function __adone() { tooenc "$(__edate)$(__eindent0)$(__eindent "$1")"; } | function __adone() { recho "$(__edate)$(__eindent0)$(__eindent "$1")"; } | ||||||
|  | |||||||
| @ -6,23 +6,23 @@ function __esection() { | |||||||
|     local length="${COLUMNS:-80}" |     local length="${COLUMNS:-80}" | ||||||
|     setx lsep=__complete "$prefix" "$length" - |     setx lsep=__complete "$prefix" "$length" - | ||||||
| 
 | 
 | ||||||
|     tooenc "$lsep" |     recho "$lsep" | ||||||
|     [ -n "$*" ] || return 0 |     [ -n "$*" ] || return 0 | ||||||
|     length=$((length - 1)) |     length=$((length - 1)) | ||||||
|     setx -a lines=echo "$1" |     setx -a lines=echo "$1" | ||||||
|     for line in "${lines[@]}"; do |     for line in "${lines[@]}"; do | ||||||
|         setx line=__complete "$prefix- $line" "$length" |         setx line=__complete "$prefix- $line" "$length" | ||||||
|         tooenc "$line-" |         recho "$line-" | ||||||
|     done |     done | ||||||
|     tooenc "$lsep" |     recho "$lsep" | ||||||
| } | } | ||||||
| function __etitle() { | function __etitle() { | ||||||
|     local p="TITLE: " i="       " |     local p="TITLE: " i="       " | ||||||
|     tooenc "$(__edate)$(__eindent0)${p}$(__eindent "$1" "$i")" |     recho "$(__edate)$(__eindent0)${p}$(__eindent "$1" "$i")" | ||||||
| } | } | ||||||
| function __edesc() { | function __edesc() { | ||||||
|     local p="DESC: " i="      " |     local p="DESC: " i="      " | ||||||
|     tooenc "$(__edate)$(__eindent0)${p}$(__eindent "$1" "$i")" |     recho "$(__edate)$(__eindent0)${p}$(__eindent "$1" "$i")" | ||||||
| } | } | ||||||
| function __ebanner() { | function __ebanner() { | ||||||
|     local -a lines |     local -a lines | ||||||
| @ -30,37 +30,37 @@ function __ebanner() { | |||||||
|     local length="${COLUMNS:-80}" |     local length="${COLUMNS:-80}" | ||||||
|     setx lsep=__complete "$prefix" "$length" = |     setx lsep=__complete "$prefix" "$length" = | ||||||
| 
 | 
 | ||||||
|     tooenc "$lsep" |     recho "$lsep" | ||||||
|     length=$((length - 1)) |     length=$((length - 1)) | ||||||
|     setx -a lines=echo "$1" |     setx -a lines=echo "$1" | ||||||
|     for line in "" "${lines[@]}" ""; do |     for line in "" "${lines[@]}" ""; do | ||||||
|         setx line=__complete "$prefix= $line" "$length" |         setx line=__complete "$prefix= $line" "$length" | ||||||
|         tooenc "$line=" |         recho "$line=" | ||||||
|     done |     done | ||||||
|     tooenc "$lsep" |     recho "$lsep" | ||||||
| } | } | ||||||
| function __eimportant() { tooenc "$(__edate)$(__eindent0)IMPORTANT! $(__eindent "$1" "           ")"; } | function __eimportant() { recho "$(__edate)$(__eindent0)IMPORTANT! $(__eindent "$1" "           ")"; } | ||||||
| function __eattention() { tooenc "$(__edate)$(__eindent0)ATTENTION! $(__eindent "$1" "           ")"; } | function __eattention() { recho "$(__edate)$(__eindent0)ATTENTION! $(__eindent "$1" "           ")"; } | ||||||
| function __eerror() { tooenc "$(__edate)$(__eindent0)ERROR: $(__eindent "$1" "       ")"; } | function __eerror() { recho "$(__edate)$(__eindent0)ERROR: $(__eindent "$1" "       ")"; } | ||||||
| function __ewarn() { tooenc "$(__edate)$(__eindent0)WARNING: $(__eindent "$1" "         ")"; } | function __ewarn() { recho "$(__edate)$(__eindent0)WARNING: $(__eindent "$1" "         ")"; } | ||||||
| function __enote() { tooenc "$(__edate)$(__eindent0)NOTE: $(__eindent "$1" "      ")"; } | function __enote() { recho "$(__edate)$(__eindent0)NOTE: $(__eindent "$1" "      ")"; } | ||||||
| function __einfo() { tooenc "$(__edate)$(__eindent0)INFO: $(__eindent "$1" "      ")"; } | function __einfo() { recho "$(__edate)$(__eindent0)INFO: $(__eindent "$1" "      ")"; } | ||||||
| function __edebug() { tooenc "$(__edate)$(__eindent0)DEBUG: $(__eindent "$1" "       ")"; } | function __edebug() { recho "$(__edate)$(__eindent0)DEBUG: $(__eindent "$1" "       ")"; } | ||||||
| function __eecho() { tooenc "$(__edate)$(__eindent0)$(__eindent "$1")"; } | function __eecho() { recho "$(__edate)$(__eindent0)$(__eindent "$1")"; } | ||||||
| function __eecho_() { tooenc_ "$(__edate)$(__eindent0)$(__eindent "$1")"; } | function __eecho_() { recho_ "$(__edate)$(__eindent0)$(__eindent "$1")"; } | ||||||
| 
 | 
 | ||||||
| function __estep() { tooenc  "$(__edate)$(__eindent0). $(__eindent "$1" "  ")"; } | function __estep() { recho  "$(__edate)$(__eindent0). $(__eindent "$1" "  ")"; } | ||||||
| function __estepe() { tooenc  "$(__edate)$(__eindent0).E $(__eindent "$1" "   ")"; } | function __estepe() { recho  "$(__edate)$(__eindent0).E $(__eindent "$1" "   ")"; } | ||||||
| function __estepw() { tooenc  "$(__edate)$(__eindent0).W $(__eindent "$1" "   ")"; } | function __estepw() { recho  "$(__edate)$(__eindent0).W $(__eindent "$1" "   ")"; } | ||||||
| function __estepn() { tooenc  "$(__edate)$(__eindent0).N $(__eindent "$1" "   ")"; } | function __estepn() { recho  "$(__edate)$(__eindent0).N $(__eindent "$1" "   ")"; } | ||||||
| function __estepi() { tooenc  "$(__edate)$(__eindent0).I $(__eindent "$1" "   ")"; } | function __estepi() { recho  "$(__edate)$(__eindent0).I $(__eindent "$1" "   ")"; } | ||||||
| function __estep_() { tooenc_ "$(__edate)$(__eindent0). $(__eindent "$1" "  ")"; } | function __estep_() { recho_ "$(__edate)$(__eindent0). $(__eindent "$1" "  ")"; } | ||||||
| function __estepe_() { tooenc_ "$(__edate)$(__eindent0).E $(__eindent "$1" "   ")"; } | function __estepe_() { recho_ "$(__edate)$(__eindent0).E $(__eindent "$1" "   ")"; } | ||||||
| function __estepw_() { tooenc_ "$(__edate)$(__eindent0).W $(__eindent "$1" "   ")"; } | function __estepw_() { recho_ "$(__edate)$(__eindent0).W $(__eindent "$1" "   ")"; } | ||||||
| function __estepn_() { tooenc_ "$(__edate)$(__eindent0).N $(__eindent "$1" "   ")"; } | function __estepn_() { recho_ "$(__edate)$(__eindent0).N $(__eindent "$1" "   ")"; } | ||||||
| function __estepi_() { tooenc_ "$(__edate)$(__eindent0).I $(__eindent "$1" "   ")"; } | function __estepi_() { recho_ "$(__edate)$(__eindent0).I $(__eindent "$1" "   ")"; } | ||||||
| 
 | 
 | ||||||
| function __action() { tooenc "$(__edate)$(__eindent0)ACTION: $(__eindent "$1" "        ")"; } | function __action() { recho "$(__edate)$(__eindent0)ACTION: $(__eindent "$1" "        ")"; } | ||||||
| function __asuccess() { tooenc "$(__edate)$(__eindent0)(OK) $(__eindent "$1" "     ")"; } | function __asuccess() { recho "$(__edate)$(__eindent0)(OK) $(__eindent "$1" "     ")"; } | ||||||
| function __afailure() { tooenc "$(__edate)$(__eindent0)(KO) $(__eindent "$1" "     ")"; } | function __afailure() { recho "$(__edate)$(__eindent0)(KO) $(__eindent "$1" "     ")"; } | ||||||
| function __adone() { tooenc "$(__edate)$(__eindent0)$(__eindent "$1")"; } | function __adone() { recho "$(__edate)$(__eindent0)$(__eindent "$1")"; } | ||||||
|  | |||||||
| @ -124,8 +124,8 @@ optdesc | |||||||
|   commence par ++, c'est une option avancée qui n'est pas affichée par défaut." |   commence par ++, c'est une option avancée qui n'est pas affichée par défaut." | ||||||
| function parse_args() { | function parse_args() { | ||||||
|     eval "$NULIB__DISABLE_SET_X" |     eval "$NULIB__DISABLE_SET_X" | ||||||
|  |     [ -n "$NULIB_ARGS_ONERROR_RETURN" ] && set_die_return | ||||||
|     local __r= |     local __r= | ||||||
|     local __DIE='[ -n "$NULIB_ARGS_ONERROR_RETURN" ] && return 1 || die' |  | ||||||
| 
 | 
 | ||||||
|     if ! is_array args; then |     if ! is_array args; then | ||||||
|         eerror "Invalid args definition: args must be defined" |         eerror "Invalid args definition: args must be defined" | ||||||
| @ -145,17 +145,33 @@ function parse_args() { | |||||||
|         __r=1 |         __r=1 | ||||||
|     else |     else | ||||||
|         __DEFS=("$@") |         __DEFS=("$@") | ||||||
|         __parse_args || __r=1 |         __nulib_args_parse_args || __r=1 | ||||||
|     fi |     fi | ||||||
|     eval "$NULIB__ENABLE_SET_X" |     eval "$NULIB__ENABLE_SET_X" | ||||||
|     if [ -n "$__r" ]; then |     if [ -n "$__r" ]; then | ||||||
|         eval "$__DIE" |         die || return | ||||||
|     fi |     fi | ||||||
| } | } | ||||||
| function __parse_args() { | function __nulib_args_add_sopt() { | ||||||
|  |     local noauto="$1"; shift | ||||||
|  |     local def | ||||||
|  |     for def in "$@"; do | ||||||
|  |         array_contains "$noauto" "$def" || __sopts="$__sopts$def" | ||||||
|  |     done | ||||||
|  | } | ||||||
|  | function __nulib_args_add_lopt() { | ||||||
|  |     local noauto="$1"; shift | ||||||
|  |     local def | ||||||
|  |     for def in "$@"; do | ||||||
|  |         array_contains "$noauto" "$def" || __lopts="$__lopts${__lopts:+,}$def" | ||||||
|  |     done | ||||||
|  | } | ||||||
|  | function __nulib_args_parse_args() { | ||||||
|     ## tout d'abord, construire la liste des options |     ## tout d'abord, construire la liste des options | ||||||
|     local __AUTOH=1 __AUTOHELP=1 # faut-il gérer automatiquement l'affichage de l'aide? |     local __AUTOH=1 __AUTOHELP=1 # faut-il gérer automatiquement l'affichage de l'aide? | ||||||
|     local __AUTOD=1 __AUTODEBUG=1 # faut-il rajouter les options -D et --debug |     local -a __NOAUTOL __NOAUTOLOGTO # faut-il rajouter les options pour gérer la journalisation? | ||||||
|  |     local -a __NOAUTOV __NOAUTOVERBOSITY # options de verbosité qui ont été définies par l'utilisateur | ||||||
|  |     local -a __NOAUTOI __NOAUTOINTERACTION # options d'interaction qui ont été définies par l'utilisateur | ||||||
|     local __ADVHELP # y a-t-il des options avancées? |     local __ADVHELP # y a-t-il des options avancées? | ||||||
|     local __popt __sopts __lopts |     local __popt __sopts __lopts | ||||||
|     local -a __defs |     local -a __defs | ||||||
| @ -165,10 +181,10 @@ function __parse_args() { | |||||||
|         +) __popt="$1"; shift; continue;; |         +) __popt="$1"; shift; continue;; | ||||||
|         -) __popt="$1"; shift; continue;; |         -) __popt="$1"; shift; continue;; | ||||||
|         -*) IFS=, read -a __defs <<<"$1"; shift;; |         -*) IFS=, read -a __defs <<<"$1"; shift;; | ||||||
|         *) eerror "Invalid arg definition: expected option, got '$1'"; eval "$__DIE";; |         *) die "Invalid arg definition: expected option, got '$1'" || return;; | ||||||
|         esac |         esac | ||||||
|         # est-ce que l'option prend un argument? |         # est-ce que l'option prend un argument? | ||||||
|         local __def __witharg __valdesc |         local __def __longdef __witharg __valdesc | ||||||
|         __witharg= |         __witharg= | ||||||
|         for __def in "${__defs[@]}"; do |         for __def in "${__defs[@]}"; do | ||||||
|             if [ "${__def%::*}" != "$__def" ]; then |             if [ "${__def%::*}" != "$__def" ]; then | ||||||
| @ -180,23 +196,36 @@ function __parse_args() { | |||||||
|         # définitions __sopts et __lopts |         # définitions __sopts et __lopts | ||||||
|         for __def in "${__defs[@]}"; do |         for __def in "${__defs[@]}"; do | ||||||
|             __def="${__def%%:*}" |             __def="${__def%%:*}" | ||||||
|  |             __longdef= | ||||||
|             if [[ "$__def" == --* ]]; then |             if [[ "$__def" == --* ]]; then | ||||||
|                 # --longopt |                 # --longopt | ||||||
|                 __def="${__def#--}" |                 __def="${__def#--}" | ||||||
|                 __lopts="$__lopts${__lopts:+,}$__def$__witharg" |                 __lopts="$__lopts${__lopts:+,}$__def$__witharg" | ||||||
|  |                 __longdef=1 | ||||||
|             elif [[ "$__def" == -* ]] && [ ${#__def} -eq 2 ]; then |             elif [[ "$__def" == -* ]] && [ ${#__def} -eq 2 ]; then | ||||||
|                 # -o |                 # -o | ||||||
|                 __def="${__def#-}" |                 __def="${__def#-}" | ||||||
|                 __sopts="$__sopts$__def$__witharg" |                 __sopts="$__sopts$__def$__witharg" | ||||||
|                 [ "$__def" == h ] && __AUTOH= |                 case "$__def" in | ||||||
|                 [ "$__def" == D ] && __AUTOD= |                 h) __AUTOH=;; | ||||||
|  |                 L) __NOAUTOL+=("-$__def");; | ||||||
|  |                 Q|q|v|D) __NOAUTOV+=("-$__def");; | ||||||
|  |                 b|y|i) __NOAUTOI+=("-$__def");; | ||||||
|  |                 esac | ||||||
|             else |             else | ||||||
|                 # -longopt ou longopt |                 # -longopt ou longopt | ||||||
|                 __def="${__def#-}" |                 __def="${__def#-}" | ||||||
|                 __lopts="$__lopts${__lopts:+,}$__def$__witharg" |                 __lopts="$__lopts${__lopts:+,}$__def$__witharg" | ||||||
|  |                 __longdef=1 | ||||||
|  |             fi | ||||||
|  |             if [ -n "$__longdef" ]; then | ||||||
|  |                 case "$__def" in | ||||||
|  |                 help|help++) __AUTOHELP=;; | ||||||
|  |                 log-to) __NOAUTOLOGTO+=("--$__def");; | ||||||
|  |                 very-quiet|quiet|verbose|debug) __NOAUTOVERBOSITY+=("--$__def");; | ||||||
|  |                 batch|automatic|interactive) __NOAUTOINTERACTION+=("--$__def");; | ||||||
|  |                 esac | ||||||
|             fi |             fi | ||||||
|             [ "$__def" == help -o "$__def" == help++ ] && __AUTOHELP= |  | ||||||
|             [ "$__def" == debug ] && __AUTODEBUG= |  | ||||||
|         done |         done | ||||||
|         # sauter l'action |         # sauter l'action | ||||||
|         shift |         shift | ||||||
| @ -209,8 +238,12 @@ function __parse_args() { | |||||||
| 
 | 
 | ||||||
|     [ -n "$__AUTOH" ] && __sopts="${__sopts}h" |     [ -n "$__AUTOH" ] && __sopts="${__sopts}h" | ||||||
|     [ -n "$__AUTOHELP" ] && __lopts="$__lopts${__lopts:+,}help,help++" |     [ -n "$__AUTOHELP" ] && __lopts="$__lopts${__lopts:+,}help,help++" | ||||||
|     [ -n "$__AUTOD" ] && __sopts="${__sopts}D" |     __nulib_args_add_sopt __NOAUTOL L | ||||||
|     [ -n "$__AUTODEBUG" ] && __lopts="$__lopts${__lopts:+,}debug" |     __nulib_args_add_lopt __NOAUTOLOGTO log-to | ||||||
|  |     __nulib_args_add_sopt __NOAUTOV Q q v D | ||||||
|  |     __nulib_args_add_lopt __NOAUTOVERBOSITY very-quiet quiet verbose debug | ||||||
|  |     __nulib_args_add_sopt __NOAUTOI b y i | ||||||
|  |     __nulib_args_add_lopt __NOAUTOINTERACTION batch automatic interactive | ||||||
| 
 | 
 | ||||||
|     __sopts="$__popt$__sopts" |     __sopts="$__popt$__sopts" | ||||||
|     local -a __getopt_args |     local -a __getopt_args | ||||||
| @ -222,7 +255,7 @@ function __parse_args() { | |||||||
|     else |     else | ||||||
|         # relancer pour avoir le message d'erreur |         # relancer pour avoir le message d'erreur | ||||||
|         LANG=C getopt "${__getopt_args[@]}" 2>&1 1>/dev/null |         LANG=C getopt "${__getopt_args[@]}" 2>&1 1>/dev/null | ||||||
|         eval "$__DIE" |         die || return | ||||||
|     fi |     fi | ||||||
| 
 | 
 | ||||||
|     ## puis traiter les options |     ## puis traiter les options | ||||||
| @ -373,7 +406,7 @@ $prefix$usage" | |||||||
|             fi |             fi | ||||||
|             [[ "$1" == -* ]] || break |             [[ "$1" == -* ]] || break | ||||||
|             option_="$1"; shift |             option_="$1"; shift | ||||||
|             __parse_opt "$option_" |             __nulib_args_parse_opt "$option_" | ||||||
|             if [ -n "$__witharg" ]; then |             if [ -n "$__witharg" ]; then | ||||||
|                 # l'option prend un argument |                 # l'option prend un argument | ||||||
|                 value_="$1"; shift |                 value_="$1"; shift | ||||||
| @ -387,7 +420,7 @@ $prefix$usage" | |||||||
|     unset -f inc@ res@ add@ set@ showhelp@ |     unset -f inc@ res@ add@ set@ showhelp@ | ||||||
|     args=("$@") |     args=("$@") | ||||||
| } | } | ||||||
| function __parse_opt() { | function __nulib_args_parse_opt() { | ||||||
|     # $1 est l'option spécifiée |     # $1 est l'option spécifiée | ||||||
|     local option_="$1" |     local option_="$1" | ||||||
|     set -- "${__DEFS[@]}" |     set -- "${__DEFS[@]}" | ||||||
| @ -460,27 +493,62 @@ function __parse_opt() { | |||||||
| 
 | 
 | ||||||
|         [ -n "$__found" ] && return 0 |         [ -n "$__found" ] && return 0 | ||||||
|     done |     done | ||||||
|     if [ -n "$__AUTOH" -a "$option_" == -h ]; then |     case "$option_" in | ||||||
|         __action="showhelp@" |     -h) | ||||||
|         return 0 |         if [ -n "$__AUTOH" ]; then | ||||||
|     fi |             __action='showhelp@' | ||||||
|     if [ -n "$__AUTOHELP" ]; then |  | ||||||
|         if [ "$option_" == --help ]; then |  | ||||||
|             __action="showhelp@" |  | ||||||
|             return 0 |  | ||||||
|         elif [ "$option_" == --help++ ]; then |  | ||||||
|             __action="showhelp@ ++" |  | ||||||
|             return 0 |             return 0 | ||||||
|         fi |         fi | ||||||
|     fi |         ;; | ||||||
|     if [ -n "$__AUTOD" -a "$option_" == -D ]; then |     --help) | ||||||
|         __action=set_debug |         if [ -n "$__AUTOHELP" ]; then | ||||||
|         return 0 |             __action='showhelp@' | ||||||
|     fi |             return 0 | ||||||
|     if [ -n "$__AUTODEBUG" -a "$option_" == --debug ]; then |         fi | ||||||
|         __action=set_debug |         ;; | ||||||
|         return 0 |     --help++) | ||||||
|     fi |         if [ -n "$__AUTOHELP" ]; then | ||||||
|  |             __action='showhelp@ ++' | ||||||
|  |             return 0 | ||||||
|  |         fi | ||||||
|  |         ;; | ||||||
|  |     -L) | ||||||
|  |         if ! array_contains __NOAUTOL "$option_"; then | ||||||
|  |             __action='elogto $value_' | ||||||
|  |             return 0 | ||||||
|  |         fi | ||||||
|  |         ;; | ||||||
|  |     --log-to) | ||||||
|  |         if ! array_contains __NOAUTOL "$option_"; then | ||||||
|  |             __action='elogto $value_' | ||||||
|  |             return 0 | ||||||
|  |         fi | ||||||
|  |         ;; | ||||||
|  |     -Q|-q|-v|-D) | ||||||
|  |         if ! array_contains __NOAUTOV "$option_"; then | ||||||
|  |             __action='set_verbosity $option_' | ||||||
|  |             return 0 | ||||||
|  |         fi | ||||||
|  |         ;; | ||||||
|  |     --very-quiet|--quiet|--verbose|--debug) | ||||||
|  |         if ! array_contains __NOAUTOVERBOSITY "$option_"; then | ||||||
|  |             __action='set_verbosity $option_' | ||||||
|  |             return 0 | ||||||
|  |         fi | ||||||
|  |         ;; | ||||||
|  |     -b|-y|-i) | ||||||
|  |         if ! array_contains __NOAUTOI "$option_"; then | ||||||
|  |             __action='set_interaction $option_' | ||||||
|  |             return 0 | ||||||
|  |         fi | ||||||
|  |         ;; | ||||||
|  |     --batch|--automatic|--interactive) | ||||||
|  |         if ! array_contains __NOAUTOINTERACTION "$option_"; then | ||||||
|  |             __action='set_interaction $option_' | ||||||
|  |             return 0 | ||||||
|  |         fi | ||||||
|  |         ;; | ||||||
|  |     esac | ||||||
|     # ici, l'option n'a pas été trouvée, on ne devrait pas arriver ici |     # ici, l'option n'a pas été trouvée, on ne devrait pas arriver ici | ||||||
|     eerror "Unexpected option '$option_'"; eval "$__DIE" |     die "Unexpected option '$option_'" || return | ||||||
| } | } | ||||||
|  | |||||||
| @ -62,7 +62,7 @@ function ask_yesno() { | |||||||
|         else |         else | ||||||
|             __eecho_ "Voulez-vous continuer?" 1>&2 |             __eecho_ "Voulez-vous continuer?" 1>&2 | ||||||
|         fi |         fi | ||||||
|         tooenc_ " $prompt " 1>&2 |         echo_ " $prompt " 1>&2 | ||||||
|         uread r |         uread r | ||||||
|         is_yes "${r:-$default}" |         is_yes "${r:-$default}" | ||||||
|     else |     else | ||||||
| @ -198,17 +198,17 @@ function __rv_read() { | |||||||
|             __eecho_ "Entrez la valeur" 1>&2 |             __eecho_ "Entrez la valeur" 1>&2 | ||||||
|         fi |         fi | ||||||
|         if [ -n "$__rv_readline" ]; then |         if [ -n "$__rv_readline" ]; then | ||||||
|             tooenc_ ": " 1>&2 |             echo_ ": " 1>&2 | ||||||
|             uread -e ${__rv_d:+-i"$__rv_d"} "${__rv_opts[@]}" __rv_r |             uread -e ${__rv_d:+-i"$__rv_d"} "${__rv_opts[@]}" __rv_r | ||||||
|         else |         else | ||||||
|             if [ -n "$__rv_d" ]; then |             if [ -n "$__rv_d" ]; then | ||||||
|                 if [ -n "$__rv_showdef" ]; then |                 if [ -n "$__rv_showdef" ]; then | ||||||
|                     tooenc_ " [$__rv_d]" 1>&2 |                     echo_ " [$__rv_d]" 1>&2 | ||||||
|                 else |                 else | ||||||
|                     tooenc_ " [****]" 1>&2 |                     echo_ " [****]" 1>&2 | ||||||
|                 fi |                 fi | ||||||
|             fi |             fi | ||||||
|             tooenc_ ": " 1>&2 |             echo_ ": " 1>&2 | ||||||
|             uread "${__rv_opts[@]}" __rv_r |             uread "${__rv_opts[@]}" __rv_r | ||||||
|             [ -n "$__rv_nl" ] && echo |             [ -n "$__rv_nl" ] && echo | ||||||
|         fi |         fi | ||||||
| @ -217,6 +217,7 @@ function __rv_read() { | |||||||
|             _setv "$__rv_v" "$__rv_r" |             _setv "$__rv_v" "$__rv_r" | ||||||
|             return 0 |             return 0 | ||||||
|         fi |         fi | ||||||
|  |         echo | ||||||
|     done |     done | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -268,7 +269,7 @@ function simple_menu() { | |||||||
|         else |         else | ||||||
|             __eecho_ "Entrez le numéro de l'option choisie" 1>&2 |             __eecho_ "Entrez le numéro de l'option choisie" 1>&2 | ||||||
|         fi |         fi | ||||||
|         tooenc_ ": " 1>&2 |         echo_ ": " 1>&2 | ||||||
|         uread __sm_choice |         uread __sm_choice | ||||||
| 
 | 
 | ||||||
|         # Valeur par défaut |         # Valeur par défaut | ||||||
| @ -291,7 +292,7 @@ function simple_menu() { | |||||||
|         let __sm_c=$__sm_c+1 |         let __sm_c=$__sm_c+1 | ||||||
|         if [ "$__sm_c" -eq 5 ]; then |         if [ "$__sm_c" -eq 5 ]; then | ||||||
|             # sauter une ligne toutes les 4 tentatives |             # sauter une ligne toutes les 4 tentatives | ||||||
|             tooenc "" 1>&2 |             echo 1>&2 | ||||||
|             __sm_c=0 |             __sm_c=0 | ||||||
|         fi |         fi | ||||||
|     done |     done | ||||||
| @ -438,7 +439,7 @@ function __void_actions_menu() { | |||||||
|         if [ $c -eq 0 ]; then |         if [ $c -eq 0 ]; then | ||||||
|             [ -n "$title" ] && __etitle "$title" 1>&2 |             [ -n "$title" ] && __etitle "$title" 1>&2 | ||||||
|             __eecho_ "=== Actions disponibles: " 1>&2 |             __eecho_ "=== Actions disponibles: " 1>&2 | ||||||
|             tooenc "$action_title" 1>&2 |             recho "$action_title" 1>&2 | ||||||
|         fi |         fi | ||||||
|         if [ -n "$actyc" ]; then |         if [ -n "$actyc" ]; then | ||||||
|             __eecho_ "$actyc" 1>&2 |             __eecho_ "$actyc" 1>&2 | ||||||
| @ -447,7 +448,7 @@ function __void_actions_menu() { | |||||||
|         else |         else | ||||||
|             __eecho_ "Entrez l'action à effectuer" 1>&2 |             __eecho_ "Entrez l'action à effectuer" 1>&2 | ||||||
|         fi |         fi | ||||||
|         tooenc_ ": " 1>&2 |         echo_ ": " 1>&2 | ||||||
|         uread choice |         uread choice | ||||||
|         if [ -z "$choice" -a -n "$default_action" ]; then |         if [ -z "$choice" -a -n "$default_action" ]; then | ||||||
|             select_action="$default_action" |             select_action="$default_action" | ||||||
| @ -468,7 +469,7 @@ function __void_actions_menu() { | |||||||
|         let c=$c+1 |         let c=$c+1 | ||||||
|         if [ $c -eq 5 ]; then |         if [ $c -eq 5 ]; then | ||||||
|             # sauter une ligne toutes les 4 tentatives |             # sauter une ligne toutes les 4 tentatives | ||||||
|             tooenc "" 1>&2 |             echo 1>&2 | ||||||
|             c=0 |             c=0 | ||||||
|         fi |         fi | ||||||
|     done |     done | ||||||
| @ -484,21 +485,21 @@ function __options_actions_menu() { | |||||||
|             i=1 |             i=1 | ||||||
|             for option in "${options[@]}"; do |             for option in "${options[@]}"; do | ||||||
|                 if [ "$option" == "$select_option" ]; then |                 if [ "$option" == "$select_option" ]; then | ||||||
|                     tooenc "$i*- $option" 1>&2 |                     echo "$i*- $option" 1>&2 | ||||||
|                 else |                 else | ||||||
|                     tooenc "$i - $option" 1>&2 |                     echo "$i - $option" 1>&2 | ||||||
|                 fi |                 fi | ||||||
|                 let i=$i+1 |                 let i=$i+1 | ||||||
|             done |             done | ||||||
|             __estepn_ "Actions disponibles: " 1>&2 |             __estepn_ "Actions disponibles: " 1>&2 | ||||||
|             tooenc "$action_title" 1>&2 |             recho "$action_title" 1>&2 | ||||||
|         fi |         fi | ||||||
|         if [ -n "$optyc" ]; then |         if [ -n "$optyc" ]; then | ||||||
|             __eecho_ "$optyc" 1>&2 |             __eecho_ "$optyc" 1>&2 | ||||||
|         else |         else | ||||||
|             __eecho_ "Entrez l'action et le numéro de l'option choisie" 1>&2 |             __eecho_ "Entrez l'action et le numéro de l'option choisie" 1>&2 | ||||||
|         fi |         fi | ||||||
|         tooenc_ ": " 1>&2 |         echo_ ": " 1>&2 | ||||||
|         uread choice |         uread choice | ||||||
| 
 | 
 | ||||||
|         # vérifier la saisie |         # vérifier la saisie | ||||||
| @ -572,7 +573,7 @@ function __options_actions_menu() { | |||||||
|         let c=$c+1 |         let c=$c+1 | ||||||
|         if [ $c -eq 5 ]; then |         if [ $c -eq 5 ]; then | ||||||
|             # sauter une ligne toutes les 4 tentatives |             # sauter une ligne toutes les 4 tentatives | ||||||
|             tooenc "" 1>&2 |             echo "" 1>&2 | ||||||
|             c=0 |             c=0 | ||||||
|         fi |         fi | ||||||
|     done |     done | ||||||
|  | |||||||
| @ -83,7 +83,7 @@ function err_isatty() { | |||||||
| 
 | 
 | ||||||
| ################################################################################ | ################################################################################ | ||||||
| 
 | 
 | ||||||
| function tooenc() { | function uecho() { | ||||||
| # $1 étant une chaine encodée en utf-8, l'afficher dans l'encoding de sortie $2 | # $1 étant une chaine encodée en utf-8, l'afficher dans l'encoding de sortie $2 | ||||||
| # qui vaut par défaut $NULIB_OUTPUT_ENCODING | # qui vaut par défaut $NULIB_OUTPUT_ENCODING | ||||||
|     local value="$1" to="${2:-$NULIB_OUTPUT_ENCODING}" |     local value="$1" to="${2:-$NULIB_OUTPUT_ENCODING}" | ||||||
| @ -93,9 +93,8 @@ function tooenc() { | |||||||
|         iconv -f -utf-8 -t "$to" <<<"$value" |         iconv -f -utf-8 -t "$to" <<<"$value" | ||||||
|     fi |     fi | ||||||
| } | } | ||||||
| function uecho() { tooenc "$*"; } |  | ||||||
| 
 | 
 | ||||||
| function tooenc_() { | function uecho_() { | ||||||
| # $1 étant une chaine encodée en utf-8, l'afficher sans passer à la ligne dans | # $1 étant une chaine encodée en utf-8, l'afficher sans passer à la ligne dans | ||||||
| # l'encoding de sortie $2 qui vaut par défaut $NULIB_OUTPUT_ENCODING | # l'encoding de sortie $2 qui vaut par défaut $NULIB_OUTPUT_ENCODING | ||||||
|     local value="$1" to="${2:-$NULIB_OUTPUT_ENCODING}" |     local value="$1" to="${2:-$NULIB_OUTPUT_ENCODING}" | ||||||
| @ -105,7 +104,6 @@ function tooenc_() { | |||||||
|         recho_ "$value" | iconv -f utf-8 -t "$to" |         recho_ "$value" | iconv -f utf-8 -t "$to" | ||||||
|     fi |     fi | ||||||
| } | } | ||||||
| function uecho_() { tooenc_ "$*"; } |  | ||||||
| 
 | 
 | ||||||
| export NULIB_QUIETLOG | export NULIB_QUIETLOG | ||||||
| export NULIB__TMPLOG | export NULIB__TMPLOG | ||||||
| @ -210,7 +208,7 @@ function __eindent() { | |||||||
| # indenter les lignes de $1, sauf la première | # indenter les lignes de $1, sauf la première | ||||||
|     local -a lines; local line first=1 |     local -a lines; local line first=1 | ||||||
|     local indent="$(__eindent0)$2" |     local indent="$(__eindent0)$2" | ||||||
|     setx -a lines=echo "$1" |     setx -a lines=recho "$1" | ||||||
|     for line in "${lines[@]}"; do |     for line in "${lines[@]}"; do | ||||||
|         if [ -n "$first" ]; then |         if [ -n "$first" ]; then | ||||||
|             recho "$line" |             recho "$line" | ||||||
| @ -232,7 +230,11 @@ function __complete() { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| PRETTYOPTS=() | PRETTYOPTS=() | ||||||
| function set_verbosity() { :;} | function set_verbosity() { | ||||||
|  |     case "$1" in | ||||||
|  |     -D|--debug) NULIB_DEBUG=1;; | ||||||
|  |     esac | ||||||
|  | } | ||||||
| function check_verbosity() { return 0; } | function check_verbosity() { return 0; } | ||||||
| function get_verbosity_option() { :;} | function get_verbosity_option() { :;} | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -2,20 +2,13 @@ | |||||||
| 
 | 
 | ||||||
| ## configuration par défaut | ## configuration par défaut | ||||||
| 
 | 
 | ||||||
| # branche upstream |  | ||||||
| UPSTREAM= | UPSTREAM= | ||||||
| # branches de développement |  | ||||||
| DEVELOP=develop | DEVELOP=develop | ||||||
| FEATURE=wip/ | FEATURE=wip/ | ||||||
| # branche de préparation de release |  | ||||||
| RELEASE=release- | RELEASE=release- | ||||||
| # branche de release |  | ||||||
| MAIN=master | MAIN=master | ||||||
| TAG_PREFIX= | TAG_PREFIX= | ||||||
| TAG_SUFFIX= | TAG_SUFFIX= | ||||||
| # branche de hotfix |  | ||||||
| HOTFIX=hotfix- | HOTFIX=hotfix- | ||||||
| # branche de distribution |  | ||||||
| DIST= | DIST= | ||||||
| # désactiver les releases automatiques? |  | ||||||
| NOAUTO= | NOAUTO= | ||||||
|  | |||||||
| @ -5,15 +5,23 @@ | |||||||
| # les branches sont mergées dans cet ordre: | # les branches sont mergées dans cet ordre: | ||||||
| # upstream --> develop --> [release -->] main --> dist | # upstream --> develop --> [release -->] main --> dist | ||||||
| #      feature _/                 hotfix _/ | #      feature _/                 hotfix _/ | ||||||
|  | 
 | ||||||
|  | # branche upstream | ||||||
| UPSTREAM= | UPSTREAM= | ||||||
|  | # branches de développement | ||||||
| DEVELOP=develop | DEVELOP=develop | ||||||
| FEATURE=wip/ | FEATURE=wip/ | ||||||
|  | # branche de préparation de release | ||||||
| RELEASE=release- | RELEASE=release- | ||||||
|  | # branche de release | ||||||
| MAIN=master | MAIN=master | ||||||
| TAG_PREFIX= | TAG_PREFIX= | ||||||
| TAG_SUFFIX= | TAG_SUFFIX= | ||||||
|  | # branche de hotfix | ||||||
| HOTFIX=hotfix- | HOTFIX=hotfix- | ||||||
|  | # branche de distribution | ||||||
| DIST= | DIST= | ||||||
|  | # désactiver les releases automatiques? | ||||||
| NOAUTO= | NOAUTO= | ||||||
| 
 | 
 | ||||||
| CONFIG_VARS=( | CONFIG_VARS=( | ||||||
| @ -151,6 +159,7 @@ function load_branches() { | |||||||
|     local what="${1:-all}"; shift |     local what="${1:-all}"; shift | ||||||
|     case "$what" in |     case "$what" in | ||||||
|     all) |     all) | ||||||
|  |         [ -n "$Origin" ] || Origin=origin | ||||||
|         setx CurrentBranch=git_get_branch |         setx CurrentBranch=git_get_branch | ||||||
|         setx -a LocalBranches=git_list_branches |         setx -a LocalBranches=git_list_branches | ||||||
|         setx -a RemoteBranches=git_list_rbranches "$Origin" |         setx -a RemoteBranches=git_list_rbranches "$Origin" | ||||||
| @ -187,12 +196,12 @@ function load_branches() { | |||||||
|         ReleaseBranch= |         ReleaseBranch= | ||||||
|         HotfixBranch= |         HotfixBranch= | ||||||
|         MainBranch= |         MainBranch= | ||||||
|         Dist=Branch |         DistBranch= | ||||||
|         for branch in "${AllBranches[@]}"; do |         for branch in "${LocalBranches[@]}"; do | ||||||
|             if [ "$branch" == "$UPSTREAM" ]; then |             if [ "$branch" == "$UPSTREAM" ]; then | ||||||
|                 UpstreamBranch="$branch" |                 UpstreamBranch="$branch" | ||||||
|             elif [[ "$branch" == "$FEATURE"* ]]; then |             elif [[ "$branch" == "$FEATURE"* ]]; then | ||||||
|                 FeatureBranch+=("$branch") |                 FeatureBranches+=("$branch") | ||||||
|             elif [ "$branch" == "$DEVELOP" ]; then |             elif [ "$branch" == "$DEVELOP" ]; then | ||||||
|                 DevelopBranch="$branch" |                 DevelopBranch="$branch" | ||||||
|             elif [[ "$branch" == "$RELEASE"* ]]; then |             elif [[ "$branch" == "$RELEASE"* ]]; then | ||||||
| @ -210,31 +219,50 @@ function load_branches() { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| function load_config() { | function load_config() { | ||||||
|  |     if [ "${ConfigFile#::}" != "$ConfigFile" ]; then | ||||||
|  |         ConfigFile="$NULIBDIR/bash/src/pman${ConfigFile#::}.conf.sh" | ||||||
|  |     fi | ||||||
|     if [ -n "$ConfigFile" ]; then |     if [ -n "$ConfigFile" ]; then | ||||||
|         source "$ConfigFile" || die || return |         source "$ConfigFile" || die || return | ||||||
|     elif [ -n "$ConfigBranch" ]; then |     elif [ -n "$ConfigBranch" ]; then | ||||||
|  |         # c'est le seul cas où ConfigFile reste vide | ||||||
|         if ! array_contains LocalBranches "$ConfigBranch"; then |         if ! array_contains LocalBranches "$ConfigBranch"; then | ||||||
|             die "$ConfigBranch: branche de configuration introuvable" || return |             die "$ConfigBranch: branche de configuration introuvable" || return | ||||||
|         else |         else | ||||||
|             ac_set_tmpfile ConfigFile |             local config | ||||||
|             git show "$ConfigBranch:.pman.conf" >"$ConfigFile" 2>/dev/null |             ac_set_tmpfile config | ||||||
|             [ -s "$ConfigFile" ] || die "$ConfigBranch: aucune configuration trouvée sur cette branche" || return |             git show "$ConfigBranch:.pman.conf" >"$config" 2>/dev/null | ||||||
|             source "$ConfigFile" |             [ -s "$config" ] || die "$ConfigBranch: aucune configuration trouvée sur cette branche" || return | ||||||
|  |             source "$config" | ||||||
|         fi |         fi | ||||||
|     elif [ -f .pman.conf ]; then |     elif [ -f .pman.conf ]; then | ||||||
|         ConfigFile="$(pwd)/.pman.conf" |         ConfigFile="$(pwd)/.pman.conf" | ||||||
|         source "$ConfigFile" |         source "$ConfigFile" | ||||||
|     elif [ -n "${MYNAME#prel}" ]; then |     elif [ -n "$1" -a -n "${MYNAME#$1}" ]; then | ||||||
|         ConfigFile="$NULIBDIR/bash/src/pman${MYNAME#$1}.conf.sh" |         ConfigFile="$NULIBDIR/bash/src/pman${MYNAME#$1}.conf.sh" | ||||||
|         source "$ConfigFile" |         source "$ConfigFile" | ||||||
|     else |     else | ||||||
|         ConfigFile="$NULIBDIR/bash/src/pman.conf.sh" |         ConfigFile="$NULIBDIR/bash/src/pman.conf.sh" | ||||||
|     fi |     fi | ||||||
|  | 
 | ||||||
|  |     # S'assurer que nulib est dans le PATH pour que les scripts utilisateurs | ||||||
|  |     # puissent utiliser les outils fournis | ||||||
|  |     export PATH="$NULIBDIR/bin:$PATH" | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| ################################################################################ | ################################################################################ | ||||||
| # Divers | # Divers | ||||||
| 
 | 
 | ||||||
|  | function resolve_should_push() { | ||||||
|  |     local quiet="$1" | ||||||
|  |     ShouldPush=1 | ||||||
|  |     if ! git_have_remote "$Origin" && [ -n "$Push" ]; then | ||||||
|  |         [ -n "$quiet" ] || enote "L'option --no-push a été forcée puisque ce dépôt n'a pas d'origine" | ||||||
|  |         ShouldPush= | ||||||
|  |     fi | ||||||
|  |     [ -z "$ShouldPush" ] && Push= | ||||||
|  | } | ||||||
|  | 
 | ||||||
| function _push_branches() { | function _push_branches() { | ||||||
|     [ ${#push_branches[*]} -gt 0 ] || return |     [ ${#push_branches[*]} -gt 0 ] || return | ||||||
|     [ -n "$Origin" ] || Origin=origin |     [ -n "$Origin" ] || Origin=origin | ||||||
|  | |||||||
| @ -108,11 +108,17 @@ function set_interaction() { | |||||||
| # set_interaction en fonction des arguments de la ligne de commande. A utiliser | # set_interaction en fonction des arguments de la ligne de commande. A utiliser | ||||||
| # de cette manière: | # de cette manière: | ||||||
| #   parse_opts ... "${PRETTYOPTS[@]}" @ args -- ... | #   parse_opts ... "${PRETTYOPTS[@]}" @ args -- ... | ||||||
| PRETTYOPTS=( | # NB: ce n'est pas nécessaire, sauf si on veut afficher ces options dans l'aide | ||||||
|  | LOGTOOPTS=( | ||||||
|     -L:,--log-to:LOGFILE '$elogto $value_' "++enregistrer les messages dans le fichier spécifié" |     -L:,--log-to:LOGFILE '$elogto $value_' "++enregistrer les messages dans le fichier spécifié" | ||||||
|  | ) | ||||||
|  | VERBOSITYOPTS=( | ||||||
|     -Q,--very-quiet,-q,--quiet,-v,--verbose,-D,--debug '$set_verbosity $option_' "++spécifier le niveau de verbiage" |     -Q,--very-quiet,-q,--quiet,-v,--verbose,-D,--debug '$set_verbosity $option_' "++spécifier le niveau de verbiage" | ||||||
|  | ) | ||||||
|  | INTERACTIONOPTS=( | ||||||
|     -b,--batch,-y,--automatic,-i,--interactive '$set_interaction $option_' "++spécifier le niveau d'interaction" |     -b,--batch,-y,--automatic,-i,--interactive '$set_interaction $option_' "++spécifier le niveau d'interaction" | ||||||
| ) | ) | ||||||
|  | PRETTYOPTS=("${LOGTOOPTS[@]}" "${VERBOSITYOPTS[@]}" "${INTERACTIONOPTS[@]}") | ||||||
| 
 | 
 | ||||||
| function show_error() { [ "$__verbosity" -ge 1 ]; } | function show_error() { [ "$__verbosity" -ge 1 ]; } | ||||||
| function show_warn() { [ "$__verbosity" -ge 2 ]; } | function show_warn() { [ "$__verbosity" -ge 2 ]; } | ||||||
|  | |||||||
							
								
								
									
										29
									
								
								bash/tests/test-interaction.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										29
									
								
								bash/tests/test-interaction.sh
									
									
									
									
									
										Executable file
									
								
							| @ -0,0 +1,29 @@ | |||||||
|  | #!/bin/bash | ||||||
|  | # -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8 | ||||||
|  | source "$(dirname -- "$0")/../src/nulib.sh" || exit 1 | ||||||
|  | #NULIB_NO_DISABLE_SET_X=1 | ||||||
|  | 
 | ||||||
|  | args=( | ||||||
|  |     "tester diverses fonctions de saisie" | ||||||
|  | ) | ||||||
|  | parse_args "$@"; set -- "${args[@]}" | ||||||
|  | 
 | ||||||
|  | estep "inter non auto non" | ||||||
|  | ask_yesno "oui ou non?"   && echo oui || echo non | ||||||
|  | estep "inter oui auto oui" | ||||||
|  | ask_yesno "oui ou non?" O && echo oui || echo non | ||||||
|  | estep "inter non auto non" | ||||||
|  | ask_yesno "oui ou non?" N && echo oui || echo non | ||||||
|  | estep "inter non auto oui" | ||||||
|  | ask_yesno "oui ou non?" C && echo oui || echo non | ||||||
|  | estep "inter oui auto non" | ||||||
|  | ask_yesno "oui ou non?" X && echo oui || echo non | ||||||
|  | 
 | ||||||
|  | estep "valeur par défaut vide" | ||||||
|  | read_value "valeur" empty "" N; echo "valeur=$empty" | ||||||
|  | 
 | ||||||
|  | estep "valeur par défaut non vide" | ||||||
|  | read_value "valeur" default default N; echo "valeur=$default" | ||||||
|  | 
 | ||||||
|  | estep "valeur requise" | ||||||
|  | read_value "valeur" required; echo "valeur=$required" | ||||||
| @ -7,7 +7,6 @@ Multiline= | |||||||
| Banner= | Banner= | ||||||
| args=( | args=( | ||||||
|     "afficher divers messages avec les fonctions e*" |     "afficher divers messages avec les fonctions e*" | ||||||
|     -D,--debug '$set_debug' |  | ||||||
|     -d,--date NULIB_ELOG_DATE=1 |     -d,--date NULIB_ELOG_DATE=1 | ||||||
|     -m,--myname NULIB_ELOG_MYNAME=1 |     -m,--myname NULIB_ELOG_MYNAME=1 | ||||||
|     -n,--nc,--no-color '$__set_no_colors 1' |     -n,--nc,--no-color '$__set_no_colors 1' | ||||||
|  | |||||||
							
								
								
									
										24
									
								
								bash/tests/test-verbosity.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										24
									
								
								bash/tests/test-verbosity.sh
									
									
									
									
									
										Executable file
									
								
							| @ -0,0 +1,24 @@ | |||||||
|  | #!/bin/bash | ||||||
|  | # -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8 | ||||||
|  | source "$(dirname -- "$0")/../src/nulib.sh" || exit 1 | ||||||
|  | #NULIB_NO_DISABLE_SET_X=1 | ||||||
|  | 
 | ||||||
|  | args=( | ||||||
|  |     "afficher divers messages avec les fonctions e*" | ||||||
|  | ) | ||||||
|  | parse_args "$@"; set -- "${args[@]}" | ||||||
|  | 
 | ||||||
|  | eimportant "important (q)" | ||||||
|  | eattention "attention (q)" | ||||||
|  | eerror "error (q)" | ||||||
|  | ewarn "warn (q)" | ||||||
|  | enote "note (qv)" | ||||||
|  | einfo "info (qv)" | ||||||
|  | eecho "echo (qv)" | ||||||
|  | edebug "debug (D)" | ||||||
|  | 
 | ||||||
|  | estep "step (qv)" | ||||||
|  | estepe "stepe (qv)" | ||||||
|  | estepw "stepw (qv)" | ||||||
|  | estepn "stepn (qv)" | ||||||
|  | estepi "stepi (qv)" | ||||||
| @ -1,4 +1,4 @@ | |||||||
| #!/bin/bash | #!/bin/bash | ||||||
| # -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8 | # -*- 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 "$@" | exec "$(dirname -- "$0")/pdev" --tech-merge -Bdev82 dev74 -a "git checkout dev74" "$@" | ||||||
|  | |||||||
							
								
								
									
										14
									
								
								bin/_pman-composer_local_deps.php
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										14
									
								
								bin/_pman-composer_local_deps.php
									
									
									
									
									
										Executable file
									
								
							| @ -0,0 +1,14 @@ | |||||||
|  | #!/usr/bin/php
 | ||||||
|  | <?php | ||||||
|  | require __DIR__ . "/../vendor/autoload.php"; | ||||||
|  | 
 | ||||||
|  | use nulib\tools\pman\ComposerFile; | ||||||
|  | use nulib\tools\pman\PmanYamlConfigFile; | ||||||
|  | use nulib\ValueException; | ||||||
|  | 
 | ||||||
|  | $composer = new ComposerFile(); | ||||||
|  | 
 | ||||||
|  | $deps = $composer->getLocalDeps(); | ||||||
|  | foreach ($deps as $dep => $path) { | ||||||
|  |   echo "$path\n"; | ||||||
|  | } | ||||||
							
								
								
									
										22
									
								
								bin/_pman-composer_select_profile.php
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										22
									
								
								bin/_pman-composer_select_profile.php
									
									
									
									
									
										Executable file
									
								
							| @ -0,0 +1,22 @@ | |||||||
|  | #!/usr/bin/php
 | ||||||
|  | <?php | ||||||
|  | require __DIR__ . "/../vendor/autoload.php"; | ||||||
|  | 
 | ||||||
|  | use nulib\tools\pman\ComposerFile; | ||||||
|  | use nulib\tools\pman\PmanYamlConfigFile; | ||||||
|  | use nulib\ValueException; | ||||||
|  | 
 | ||||||
|  | $composer = new ComposerFile(); | ||||||
|  | $config = new PmanYamlConfigFile(); | ||||||
|  | 
 | ||||||
|  | if ($argc <= 1) { | ||||||
|  |   throw new ValueException("Il faut spécifier le profil à sélectionner"); | ||||||
|  | } | ||||||
|  | $profile = $argv[1]; | ||||||
|  | 
 | ||||||
|  | $composer->selectProfile($profile, $config); | ||||||
|  | if (getenv("PMAN_COMPOSER_DEBUG")) { | ||||||
|  |   $composer->print(); | ||||||
|  | } else { | ||||||
|  |   $composer->write(); | ||||||
|  | } | ||||||
							
								
								
									
										34
									
								
								bin/p
									
									
									
									
									
								
							
							
						
						
									
										34
									
								
								bin/p
									
									
									
									
									
								
							| @ -20,8 +20,18 @@ function git_status() { | |||||||
|     fi |     fi | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | function git_statuses() { | ||||||
|  |     local cwd="$(pwd)" dir | ||||||
|  |     for dir in "$@"; do | ||||||
|  |         cd "$dir" || die | ||||||
|  |         git_status --porcelain | ||||||
|  |         cd "$cwd" | ||||||
|  |     done | ||||||
|  | } | ||||||
|  | 
 | ||||||
| chdir= | chdir= | ||||||
| all= | all= | ||||||
|  | composer= | ||||||
| args=( | args=( | ||||||
|     "afficher l'état du dépôt" |     "afficher l'état du dépôt" | ||||||
|     "[-d chdir] [-a patterns...] |     "[-d chdir] [-a patterns...] | ||||||
| @ -29,6 +39,7 @@ args=( | |||||||
| Si l'option -a est utilisée, ce script accepte comme arguments une liste de patterns permettant de filtrer les répertoires concernés" | Si l'option -a est utilisée, ce script accepte comme arguments une liste de patterns permettant de filtrer les répertoires concernés" | ||||||
|     -d:,--chdir:BASEDIR chdir= "répertoire dans lequel se placer avant de lancer les opérations" |     -d:,--chdir:BASEDIR chdir= "répertoire dans lequel se placer avant de lancer les opérations" | ||||||
|     -a,--all all=1 "faire l'opération sur tous les sous-répertoires de BASEDIR qui sont des dépôts git" |     -a,--all all=1 "faire l'opération sur tous les sous-répertoires de BASEDIR qui sont des dépôts git" | ||||||
|  |     -r,--composer composer=1 "faire l'opération sur tous les projets composer dépendants" | ||||||
| ) | ) | ||||||
| parse_args "$@"; set -- "${args[@]}" | parse_args "$@"; set -- "${args[@]}" | ||||||
| 
 | 
 | ||||||
| @ -50,16 +61,23 @@ if [ -n "$all" ]; then | |||||||
|             dirs+=("${dir%/.git}") |             dirs+=("${dir%/.git}") | ||||||
|         done |         done | ||||||
|     fi |     fi | ||||||
|     setx cwd=pwd |     git_statuses "${dirs[@]}" | ||||||
|     for dir in "${dirs[@]}"; do | 
 | ||||||
|         cd "$dir" || die | elif [ -n "$composer" ]; then | ||||||
|         git_status --porcelain |     # projets dépendants | ||||||
|         cd "$cwd" |     git_ensure_gitvcs | ||||||
|     done |     setx toplevel=git_get_toplevel | ||||||
|  |     cd "$toplevel" || die | ||||||
|  |     setx cwd=ppath2 . "$OrigCwd" | ||||||
|  |     [ -f composer.json ] || die "$cwd: ce n'est pas un projet composer" | ||||||
|  | 
 | ||||||
|  |     setx -a dirs="$MYDIR/_pman-composer_local_deps.php" | ||||||
|  |     git_statuses "${dirs[@]}" | ||||||
|  | 
 | ||||||
| else | else | ||||||
|     # répertoire courant uniquement |     # répertoire courant uniquement | ||||||
|     setx toplevel=git_get_toplevel |     git_ensure_gitvcs | ||||||
|     [ -n "$toplevel" ] && Cwd="$toplevel" |     Cwd="$(git_get_toplevel)" | ||||||
| 
 | 
 | ||||||
|     args=() |     args=() | ||||||
|     isatty || args+=(--porcelain) |     isatty || args+=(--porcelain) | ||||||
|  | |||||||
							
								
								
									
										127
									
								
								bin/pdev
									
									
									
									
									
								
							
							
						
						
									
										127
									
								
								bin/pdev
									
									
									
									
									
								
							| @ -25,6 +25,9 @@ function ensure_branches() { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| function merge_action() { | function merge_action() { | ||||||
|  |     [ -z "$ShouldPush" ] && enote "\ | ||||||
|  | L'option --no-push a été forcée puisque ce dépôt n'a pas d'origine" | ||||||
|  | 
 | ||||||
|     enote "\ |     enote "\ | ||||||
| Ce script va | Ce script va | ||||||
| - fusionner la branche ${COULEUR_BLEUE}$SrcBranch${COULEUR_NORMALE} dans ${COULEUR_ROUGE}$DestBranch${COULEUR_NORMALE}${Push:+ | - fusionner la branche ${COULEUR_BLEUE}$SrcBranch${COULEUR_NORMALE} dans ${COULEUR_ROUGE}$DestBranch${COULEUR_NORMALE}${Push:+ | ||||||
| @ -33,7 +36,7 @@ Ce script va | |||||||
| 
 | 
 | ||||||
|     local script=".git/pman-merge.sh" |     local script=".git/pman-merge.sh" | ||||||
|     local -a push_branches delete_branches |     local -a push_branches delete_branches | ||||||
|     local after |     local hook | ||||||
|     local comment= |     local comment= | ||||||
|     local or_die=" || exit 1" |     local or_die=" || exit 1" | ||||||
| 
 | 
 | ||||||
| @ -44,17 +47,22 @@ Ce script va | |||||||
| if [ -n "\$merge" ]; then | if [ -n "\$merge" ]; then | ||||||
| esection "Fusionner la branche" | esection "Fusionner la branche" | ||||||
| EOF | EOF | ||||||
|     _mscript_merge_branch |     hook="BEFORE_MERGE_${SrcType^^}"; [ -n "${!hook}" ] && _scripta <<EOF | ||||||
|     after="AFTER_MERGE_${SrcType^^}"; [ -n "${!after}" ] && _scripta <<EOF |  | ||||||
| ( | ( | ||||||
| ${!after} | ${!hook} | ||||||
|  | )$or_die | ||||||
|  | EOF | ||||||
|  |     _mscript_merge_branch | ||||||
|  |     hook="AFTER_MERGE_${SrcType^^}"; [ -n "${!hook}" ] && _scripta <<EOF | ||||||
|  | ( | ||||||
|  | ${!hook} | ||||||
| )$or_die | )$or_die | ||||||
| EOF | EOF | ||||||
|     _scripta <<EOF |     _scripta <<EOF | ||||||
| fi | fi | ||||||
| EOF | EOF | ||||||
| 
 | 
 | ||||||
|     if [ -z "$ForbidDelete" ]; then |     if [ -n "$ShouldDelete" ]; then | ||||||
|         _scripta <<EOF |         _scripta <<EOF | ||||||
| ################################################################################ | ################################################################################ | ||||||
| # delete | # delete | ||||||
| @ -62,9 +70,9 @@ if [ -n "\$delete" ]; then | |||||||
| esection "Supprimer la branche" | esection "Supprimer la branche" | ||||||
| EOF | EOF | ||||||
|         _mscript_delete_branch |         _mscript_delete_branch | ||||||
|         after="AFTER_DELETE_${SrcType^^}"; [ -n "${!after}" ] && _scripta <<EOF |         hook="AFTER_DELETE_${SrcType^^}"; [ -n "${!hook}" ] && _scripta <<EOF | ||||||
| ( | ( | ||||||
| ${!after} | ${!hook} | ||||||
| )$or_die | )$or_die | ||||||
| EOF | EOF | ||||||
|         _scripta <<EOF |         _scripta <<EOF | ||||||
| @ -77,6 +85,11 @@ EOF | |||||||
| # push | # push | ||||||
| if [ -n "\$push" ]; then | if [ -n "\$push" ]; then | ||||||
| esection "Pousser les branches" | esection "Pousser les branches" | ||||||
|  | EOF | ||||||
|  |     hook="BEFORE_PUSH_${DestType^^}"; [ -n "${!hook}" ] && _scripta <<EOF | ||||||
|  | ( | ||||||
|  | ${!hook} | ||||||
|  | )$or_die | ||||||
| EOF | EOF | ||||||
|     _script_push_branches |     _script_push_branches | ||||||
|     if [ ${#delete_branches[*]} -gt 0 ]; then |     if [ ${#delete_branches[*]} -gt 0 ]; then | ||||||
| @ -85,35 +98,42 @@ EOF | |||||||
|         _script_push_branches |         _script_push_branches | ||||||
|         _scripta <<<fi |         _scripta <<<fi | ||||||
|     fi |     fi | ||||||
|     after="AFTER_PUSH_${DestType^^}"; [ -n "${!after}" ] && _scripta <<EOF |     hook="AFTER_PUSH_${DestType^^}"; [ -n "${!hook}" ] && _scripta <<EOF | ||||||
| ( | ( | ||||||
| ${!after} | ${!hook} | ||||||
| )$or_die | )$or_die | ||||||
| EOF | EOF | ||||||
|     _scripta <<EOF |     _scripta <<EOF | ||||||
| fi | fi | ||||||
| EOF | EOF | ||||||
| 
 | 
 | ||||||
|     [ -n "$Delete" -o "$ForbidDelete" ] && Deleted=1 || Deleted= |     [ -n "$Delete" -o -z "$ShouldDelete" ] && Deleted=1 || Deleted= | ||||||
|     [ -n "$Push" -o "$CantPush" ] && Pushed=1 || Pushed= |     [ -n "$ShouldDelete" -a -n "$Delete" ] && ShouldDelete= | ||||||
|     if [ -n "$_NoRunScript" ]; then |     [ -n "$ShouldPush" -a -n "$Push" ] && ShouldPush= | ||||||
|         einfo "Veuillez consulter le script $script pour le détail des opérations à effectuer" |     if [ -n "$_Fake" ]; then | ||||||
|  |         cat "$script" | ||||||
|     elif ! "$script" merge ${Delete:+delete} ${Push:+push}; then |     elif ! "$script" merge ${Delete:+delete} ${Push:+push}; then | ||||||
|         eimportant "\ |         eimportant "\ | ||||||
| Le script $script a été lancé avec les arguments 'merge${Delete:+ delete}${Push:+ push}' | Le script $script a été lancé avec les arguments 'merge${Delete:+ delete}${Push:+ push}' | ||||||
| Veuillez le consulter pour le détail des opérations qui n'ont pas pu êtres effectuées" | En cas d'erreur de merge, veuillez corriger les erreurs puis continuer avec | ||||||
|  |     git merge --continue | ||||||
|  | Sinon, veuillez consulter le script et/ou le relancer | ||||||
|  |     ./$script${Delete:+ delete}${Push:+ push}" | ||||||
|         die |         die | ||||||
|     elif [ -n "$Deleted" -a -n "$Pushed" ]; then |     elif [ -n "$Deleted" -a -n "$Push" ]; then | ||||||
|         [ -n "$_KeepScript" ] || rm "$script" |         [ -n "$_KeepScript" ] || rm "$script" | ||||||
|  |         [ -n "$AfterMerge" ] && eval "$AfterMerge" | ||||||
|     else |     else | ||||||
|         local cmd |         local msg="\ | ||||||
|         [ -n "$Deleted" ] || cmd="$cmd |  | ||||||
|     ./$script delete" |  | ||||||
|         [ -n "$Pushed" ] || cmd="$cmd |  | ||||||
|     ./$script push" |  | ||||||
|         einfo "\ |  | ||||||
| Le script $script a été lancé avec les arguments 'merge${Delete:+ delete}${Push:+ push}' | Le script $script a été lancé avec les arguments 'merge${Delete:+ delete}${Push:+ push}' | ||||||
| Veuillez le consulter pour le détail des autres opérations à effectuer$cmd" | Vous pouvez consulter le script et/ou le relancer | ||||||
|  |     ./$script${ShouldDelete:+ delete}${ShouldPush:+ push}" | ||||||
|  |         [ -n "$AfterMerge" ] && msg="$msg | ||||||
|  | Il y a aussi les commandes supplémentaires suivantes: | ||||||
|  |     ${AfterMerge// | ||||||
|  | / | ||||||
|  |     }" | ||||||
|  |         einfo "$msg" | ||||||
|     fi |     fi | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -125,16 +145,27 @@ chdir= | |||||||
| Origin= | Origin= | ||||||
| ConfigBranch= | ConfigBranch= | ||||||
| ConfigFile= | ConfigFile= | ||||||
|  | _Fake= | ||||||
| _KeepScript= | _KeepScript= | ||||||
| _NoRunScript= |  | ||||||
| action=merge | action=merge | ||||||
| TechMerge= | TechMerge= | ||||||
| SquashMsg= | SquashMsg= | ||||||
| [ -z "$PMAN_NO_PUSH" ] && Push=1 || Push= | [ -z "$PMAN_NO_PUSH" ] && Push=1 || Push= | ||||||
| [ -z "$PMAN_NO_DELETE" ] && Delete=1 || Delete= | [ -z "$PMAN_NO_DELETE" ] && Delete=1 || Delete= | ||||||
|  | AfterMerge= | ||||||
| args=( | args=( | ||||||
|     "fusionner la branche source dans la branche destination correspondante" |     "fusionner la branche source dans la branche destination correspondante" | ||||||
|     " [source]" |     " [source] | ||||||
|  | 
 | ||||||
|  | CONFIGURATION | ||||||
|  | Le fichier .pman.conf contient la configuration des branches. Les variables | ||||||
|  | supplémentaires suivantes peuvent être définies: | ||||||
|  |     BEFORE_MERGE_<srcType> | ||||||
|  |     AFTER_MERGE_<srcType> | ||||||
|  |     AFTER_DELETE_<srcType> | ||||||
|  |     BEFORE_PUSH_<destType> | ||||||
|  |     AFTER_PUSH_<destType> | ||||||
|  | srcType et destType pouvant valoir UPSTREAM, DEVELOP, FEATURE, RELEASE, MAIN, HOTFIX, DIST" | ||||||
|     -d:,--chdir:BASEDIR chdir= "répertoire dans lequel se placer avant de lancer les opérations" |     -d:,--chdir:BASEDIR chdir= "répertoire dans lequel se placer avant de lancer les opérations" | ||||||
|     -O:,--origin Origin= "++\ |     -O:,--origin Origin= "++\ | ||||||
| origine à partir de laquelle les branches distantes sont considérées" | origine à partir de laquelle les branches distantes sont considérées" | ||||||
| @ -143,8 +174,8 @@ branche à partir de laquelle charger la configuration" | |||||||
|     -c:,--config-file:CONFIG ConfigFile= "++\ |     -c:,--config-file:CONFIG ConfigFile= "++\ | ||||||
| fichier de configuration des branches. cette option est prioritaire sur --config-branch | fichier de configuration des branches. cette option est prioritaire sur --config-branch | ||||||
| par défaut, utiliser le fichier .pman.conf dans le répertoire du dépôt s'il existe" | 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" |     --keep-script _KeepScript=1 "++option non documentée" | ||||||
|     --no-run-script _NoRunScript=1 "++option non documentée" |  | ||||||
|     -w,--show action=show "\ |     -w,--show action=show "\ | ||||||
| lister les modifications qui seraient fusionnées dans la branche destination" | lister les modifications qui seraient fusionnées dans la branche destination" | ||||||
|     -b,--rebase action=rebase "\ |     -b,--rebase action=rebase "\ | ||||||
| @ -167,6 +198,10 @@ ne pas supprimer la branche après la fusion dans la destination" | |||||||
|     --delete Delete=1 "++\ |     --delete Delete=1 "++\ | ||||||
| supprimer la branche après la fusion dans la destination. | supprimer la branche après la fusion dans la destination. | ||||||
| c'est l'option par défaut" | c'est l'option par défaut" | ||||||
|  |     -f,--force-merge ForceMerge=1 "++\ | ||||||
|  | forcer la fusion pour une branche qui devrait être traitée par prel" | ||||||
|  |     -a:,--after-merge AfterMerge= "\ | ||||||
|  | évaluer le script spécifié après une fusion *réussie*" | ||||||
| ) | ) | ||||||
| parse_args "$@"; set -- "${args[@]}" | parse_args "$@"; set -- "${args[@]}" | ||||||
| 
 | 
 | ||||||
| @ -176,13 +211,7 @@ load_branches all | |||||||
| load_config "$MYNAME" | load_config "$MYNAME" | ||||||
| load_branches current "$1" | load_branches current "$1" | ||||||
| 
 | 
 | ||||||
| CantPush= | resolve_should_push quiet | ||||||
| [ -n "$Origin" ] || Origin=origin |  | ||||||
| if ! git_have_remote "$Origin" && [ -n "$Push" ]; then |  | ||||||
|     ewarn "L'option --no-push a été forcée puisque ce dépôt n'a pas d'origine" |  | ||||||
|     CantPush=1 |  | ||||||
| fi |  | ||||||
| [ -n "$CantPush" ] && Push= |  | ||||||
| 
 | 
 | ||||||
| # puis faire l'action que l'on nous demande | # puis faire l'action que l'on nous demande | ||||||
| case "$action" in | case "$action" in | ||||||
| @ -192,24 +221,26 @@ show) | |||||||
|     show_action "$@" |     show_action "$@" | ||||||
|     ;; |     ;; | ||||||
| merge) | merge) | ||||||
|     ForbidDelete= |     ShouldDelete=1 | ||||||
|     case "$SrcType" in |     no_merge_msg="$SrcBranch: cette branche doit être fusionnée dans $DestBranch avec prel" | ||||||
|     develop|release|hotfix) |     if [ "$SrcType" == develop ]; then | ||||||
|         die "$SrcBranch: cette branche doit être fusionnée dans $DestBranch avec prel" |         [ -z "$ForceMerge" ] && die "$no_merge_msg" | ||||||
|         ;; |         [ -n "$AfterMerge" ] || setx AfterMerge=qvals git checkout -q "$SrcBranch" | ||||||
|     *) |     elif [ "$SrcType" == release -o "$SrcType" == hotfix ]; then | ||||||
|         # n'autoriser la suppression que pour feature |         die "$no_merge_msg" | ||||||
|         [ "$SrcType" == feature ] || ForbidDelete=1 |     fi | ||||||
|         ;; |     # n'autoriser la suppression que pour feature | ||||||
|     esac |     [ "$SrcType" == feature ] || ShouldDelete= | ||||||
|     [ -n "$ForbidDelete" ] && Delete= |     [ -z "$ShouldDelete" ] && Delete= | ||||||
|     git_ensure_cleancheckout |     [ -z "$_Fake" ] && git_ensure_cleancheckout | ||||||
|     if ! array_contains LocalBranches "$SrcBranch"; then |     if array_contains LocalBranches "$SrcBranch"; then | ||||||
|         # si la branche source n'existe pas, la créer |  | ||||||
|         exec "$MYDIR/pman" "$FEATURE${SrcBranch#$FEATURE}" |  | ||||||
|     else |  | ||||||
|         ensure_branches |         ensure_branches | ||||||
|         merge_action "$@" |         merge_action "$@" | ||||||
|  |     elif array_contains AllBranches "$SrcBranch"; then | ||||||
|  |         enote "$SrcBranch: une branche du même nom existe dans l'origine" | ||||||
|  |         die "$SrcBranch: branche locale introuvable" | ||||||
|  |     else | ||||||
|  |         die "$SrcBranch: branche introuvable" | ||||||
|     fi |     fi | ||||||
|     ;; |     ;; | ||||||
| *) | *) | ||||||
|  | |||||||
							
								
								
									
										140
									
								
								bin/pman
									
									
									
									
									
								
							
							
						
						
									
										140
									
								
								bin/pman
									
									
									
									
									
								
							| @ -34,16 +34,12 @@ function show_action() { | |||||||
| # Initialisation | # Initialisation | ||||||
| ################################################################################ | ################################################################################ | ||||||
| 
 | 
 | ||||||
| function init_repo_action() { | function _init_config() { | ||||||
|     [ ${#LocalBranches[*]} -eq 0 ] || die "Ce dépôt a déjà été initialisé" |     if [ ! -f .pman.conf -o -n "$ForceCreate" ]; then | ||||||
| 
 |  | ||||||
|     local -a push_branches |  | ||||||
| 
 |  | ||||||
|     if [ ! -f .pman.conf ]; then |  | ||||||
|         ac_set_tmpfile config |         ac_set_tmpfile config | ||||||
|         cp "$ConfigFile" "$config" |         cp "$ConfigFile" "$config" | ||||||
|         "${EDITOR:-nano}" "$config" |         "${EDITOR:-nano}" "$config" | ||||||
|         [ -s "$config" ] || exit_with ewarn "Initialisation du dépôt annulée" |         [ -s "$config" ] || return 1 | ||||||
| 
 | 
 | ||||||
|         cp "$config" .pman.conf |         cp "$config" .pman.conf | ||||||
|         if testdiff .pman.conf "$ConfigFile"; then |         if testdiff .pman.conf "$ConfigFile"; then | ||||||
| @ -59,6 +55,15 @@ function init_repo_action() { | |||||||
| .*.swp" | .*.swp" | ||||||
|         git add .gitignore |         git add .gitignore | ||||||
|     fi |     fi | ||||||
|  |     return 0 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | function init_repo_action() { | ||||||
|  |     local -a push_branches; local config | ||||||
|  | 
 | ||||||
|  |     [ ${#LocalBranches[*]} -eq 0 ] || die "Ce dépôt a déjà été initialisé" | ||||||
|  | 
 | ||||||
|  |     _init_config || exit_with ewarn "Initialisation du dépôt annulée" | ||||||
| 
 | 
 | ||||||
|     einfo "Création de la branche $MAIN" |     einfo "Création de la branche $MAIN" | ||||||
|     git symbolic-ref HEAD "refs/heads/$MAIN" |     git symbolic-ref HEAD "refs/heads/$MAIN" | ||||||
| @ -72,17 +77,55 @@ function init_repo_action() { | |||||||
|     _push_branches |     _push_branches | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | function init_config_action() { | ||||||
|  |     local -a push_branches; config | ||||||
|  | 
 | ||||||
|  |     [ -f .pman.conf -a -z "$ForceCreate" ] && die "La configuration pman a déjà été initialisée" | ||||||
|  | 
 | ||||||
|  |     resolve_should_push | ||||||
|  | 
 | ||||||
|  |     _init_config || exit_with ewarn "Initialisation de la configuration annulée" | ||||||
|  |     git commit -m "configuration pman" | ||||||
|  |     push_branches+=("$CurrentBranch") | ||||||
|  | 
 | ||||||
|  |     _push_branches | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | function _ensure_main_branch() { | ||||||
|  |     [ -n "$MAIN" ] || die "La branche MAIN n'a pas été définie" | ||||||
|  |     [ -n "$MainBranch" ] || die "$MAIN: cette branche n'existe pas (le dépôt a-t-il été initialisé?)" | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | function checkout_main_action() { | ||||||
|  |     if [ -z "$MainBranch" ]; then | ||||||
|  |         array_contains AllBranches "$MAIN" && exit_with enote "\ | ||||||
|  | $MAIN: une branche du même nom existe dans l'origine | ||||||
|  |     git checkout $MAIN" | ||||||
|  |         _ensure_main_branch | ||||||
|  |     fi | ||||||
|  |     git checkout -q "$MAIN" | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | function _ensure_develop_branch() { | ||||||
|  |     [ -n "$DEVELOP" ] || die "La branche DEVELOP n'a pas été définie" | ||||||
|  |     [ -n "$DevelopBranch" ] || die "$DEVELOP: cette branche n'existe pas (le dépôt a-t-il été initialisé?)" | ||||||
|  | } | ||||||
|  | 
 | ||||||
| function init_develop_action() { | function init_develop_action() { | ||||||
|  |     local -a push_branches | ||||||
|  | 
 | ||||||
|     if [ -z "$DevelopBranch" ]; then |     if [ -z "$DevelopBranch" ]; then | ||||||
|         [ -n "$DEVELOP" ] || die "La branche DEVELOP n'a pas été définie" |         array_contains AllBranches "$DEVELOP" && exit_with enote "\ | ||||||
|         [ -n "$MAIN" ] || die "La branche MAIN n'a pas été définie" | $DEVELOP: une branche du même nom existe dans l'origine | ||||||
|         [ -n "$MainBranch" ] || die "$MAIN: cette branche n'existe pas (le dépôt a-t-il été initialisé?)" |     git checkout $DEVELOP" | ||||||
|  |         _ensure_main_branch | ||||||
|  |         _ensure_develop_branch | ||||||
|  | 
 | ||||||
|  |         resolve_should_push | ||||||
| 
 | 
 | ||||||
|         enote "Vous allez créer la branche ${COULEUR_VERTE}$DEVELOP${COULEUR_NORMALE} <-- ${COULEUR_BLEUE}$MAIN${COULEUR_NORMALE}" |         enote "Vous allez créer la branche ${COULEUR_VERTE}$DEVELOP${COULEUR_NORMALE} <-- ${COULEUR_BLEUE}$MAIN${COULEUR_NORMALE}" | ||||||
|         ask_yesno "Voulez-vous continuer?" O || die |         ask_yesno "Voulez-vous continuer?" O || die | ||||||
| 
 | 
 | ||||||
|         local -a push_branches |  | ||||||
| 
 |  | ||||||
|         einfo "Création de la branche $DEVELOP" |         einfo "Création de la branche $DEVELOP" | ||||||
|         git checkout -b "$DEVELOP" "$MAIN" || die |         git checkout -b "$DEVELOP" "$MAIN" || die | ||||||
|         push_branches+=("$DEVELOP") |         push_branches+=("$DEVELOP") | ||||||
| @ -92,17 +135,26 @@ function init_develop_action() { | |||||||
|     git checkout -q "$DEVELOP" |     git checkout -q "$DEVELOP" | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | function _ensure_upstream_branch() { | ||||||
|  |     [ -n "$UPSTREAM" ] || die "La branche UPSTREAM n'a pas été définie" | ||||||
|  |     [ -n "$UpstreamBranch" ] || die "$UPSTREAM: cette branche n'existe pas (le dépôt a-t-il été initialisé?)" | ||||||
|  | } | ||||||
|  | 
 | ||||||
| function init_upstream_action() { | function init_upstream_action() { | ||||||
|  |     local -a push_branches; local config | ||||||
|  | 
 | ||||||
|     if [ -z "$UpstreamBranch" ]; then |     if [ -z "$UpstreamBranch" ]; then | ||||||
|         [ -n "$UPSTREAM" ] || die "La branche UPSTREAM n'a pas été définie" |         array_contains AllBranches "$UPSTREAM" && exit_with enote "\ | ||||||
|         [ -n "$DEVELOP" ] || die "La branche DEVELOP n'a pas été définie" | $UPSTREAM: une branche du même nom existe dans l'origine | ||||||
|         [ -n "$DevelopBranch" ] || die "$DEVELOP: cette branche n'existe pas (le dépôt a-t-il été initialisé?)" |     git checkout $UPSTREAM" | ||||||
|  |         _ensure_develop_branch | ||||||
|  |         _ensure_upstream_branch | ||||||
|  | 
 | ||||||
|  |         resolve_should_push | ||||||
| 
 | 
 | ||||||
|         enote "Vous allez créer la branche ${COULEUR_VERTE}$UPSTREAM${COULEUR_NORMALE}" |         enote "Vous allez créer la branche ${COULEUR_VERTE}$UPSTREAM${COULEUR_NORMALE}" | ||||||
|         ask_yesno "Voulez-vous continuer?" O || die |         ask_yesno "Voulez-vous continuer?" O || die | ||||||
| 
 | 
 | ||||||
|         local -a push_branches; local config |  | ||||||
| 
 |  | ||||||
|         # faire une copie de la configuration actuelle |         # faire une copie de la configuration actuelle | ||||||
|         ac_set_tmpfile config |         ac_set_tmpfile config | ||||||
|         cp "$ConfigFile" "$config" |         cp "$ConfigFile" "$config" | ||||||
| @ -128,17 +180,26 @@ function init_upstream_action() { | |||||||
|     git checkout -q "$UPSTREAM" |     git checkout -q "$UPSTREAM" | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | function _ensure_dist_branch() { | ||||||
|  |     [ -n "$DIST" ] || die "La branche DIST n'a pas été définie" | ||||||
|  |     [ -n "$DistBranch" ] || die "$DIST: cette branche n'existe pas (le dépôt a-t-il été initialisé?)" | ||||||
|  | } | ||||||
|  | 
 | ||||||
| function init_dist_action() { | function init_dist_action() { | ||||||
|  |     local -a push_branches | ||||||
|  | 
 | ||||||
|     if [ -z "$DistBranch" ]; then |     if [ -z "$DistBranch" ]; then | ||||||
|         [ -n "$DIST" ] || die "La branche DIST n'a pas été définie" |         array_contains AllBranches "$DIST" && exit_with enote "\ | ||||||
|         [ -n "$MAIN" ] || die "La branche MAIN n'a pas été définie" | $DIST: une branche du même nom existe dans l'origine | ||||||
|         [ -n "$MainBranch" ] || die "$MAIN: cette branche n'existe pas (le dépôt a-t-il été initialisé?)" |     git checkout $DIST" | ||||||
|  |         _ensure_main_branch | ||||||
|  |         _ensure_dist_branch | ||||||
|  | 
 | ||||||
|  |         resolve_should_push | ||||||
| 
 | 
 | ||||||
|         enote "Vous allez créer la branche ${COULEUR_VERTE}$DIST${COULEUR_NORMALE} <-- ${COULEUR_BLEUE}$MAIN${COULEUR_NORMALE}" |         enote "Vous allez créer la branche ${COULEUR_VERTE}$DIST${COULEUR_NORMALE} <-- ${COULEUR_BLEUE}$MAIN${COULEUR_NORMALE}" | ||||||
|         ask_yesno "Voulez-vous continuer?" O || die |         ask_yesno "Voulez-vous continuer?" O || die | ||||||
| 
 | 
 | ||||||
|         local -a push_branches |  | ||||||
| 
 |  | ||||||
|         einfo "Création de la branche $DIST" |         einfo "Création de la branche $DIST" | ||||||
|         git checkout -b "$DIST" "$MAIN" || die |         git checkout -b "$DIST" "$MAIN" || die | ||||||
|         push_branches+=("$DIST") |         push_branches+=("$DIST") | ||||||
| @ -149,18 +210,24 @@ function init_dist_action() { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| function init_feature_action() { | function init_feature_action() { | ||||||
|     local branch="${1#$FEATURE}" |     local -a push_branches; local branch | ||||||
|     [ -n "$branch" ] || die "Vous devez définir la nom de la branche à créer" | 
 | ||||||
|  |     [ -n "$FEATURE" ] || die "La branche FEATURE n'a pas été définie" | ||||||
|  |     branch="${1#$FEATURE}" | ||||||
|  |     [ -n "$branch" ] || die "Vous devez spécifier le nom de la branche" | ||||||
|     branch="$FEATURE$branch" |     branch="$FEATURE$branch" | ||||||
|     if ! array_contains AllBranches "$branch"; then | 
 | ||||||
|         [ -n "$DEVELOP" ] || die "La branche DEVELOP n'a pas été définie" |     if ! array_contains LocalBranches "$branch"; then | ||||||
|         [ -n "$DevelopBranch" ] || die "$DEVELOP: cette branche n'existe pas (le dépôt a-t-il été initialisé?)" |         array_contains AllBranches "$branch" && exit_with enote "\ | ||||||
|  | $branch: une branche du même nom existe dans l'origine | ||||||
|  |     git checkout $branch" | ||||||
|  |         _ensure_develop_branch | ||||||
|  | 
 | ||||||
|  |         resolve_should_push | ||||||
| 
 | 
 | ||||||
|         enote "Vous allez créer la branche ${COULEUR_VERTE}$branch${COULEUR_NORMALE} <-- ${COULEUR_BLEUE}$DEVELOP${COULEUR_NORMALE}" |         enote "Vous allez créer la branche ${COULEUR_VERTE}$branch${COULEUR_NORMALE} <-- ${COULEUR_BLEUE}$DEVELOP${COULEUR_NORMALE}" | ||||||
|         ask_yesno "Voulez-vous continuer?" O || die |         ask_yesno "Voulez-vous continuer?" O || die | ||||||
| 
 | 
 | ||||||
|         local -a push_branches |  | ||||||
| 
 |  | ||||||
|         einfo "Création de la branche $branch" |         einfo "Création de la branche $branch" | ||||||
|         git checkout -b "$branch" "$DEVELOP" || die |         git checkout -b "$branch" "$DEVELOP" || die | ||||||
|         push_branches+=("$branch") |         push_branches+=("$branch") | ||||||
| @ -174,7 +241,8 @@ function init_action() { | |||||||
|     local what="${1:-develop}"; shift |     local what="${1:-develop}"; shift | ||||||
|     case "$what" in |     case "$what" in | ||||||
|     init|repo|r) init_repo_action "$@";; |     init|repo|r) init_repo_action "$@";; | ||||||
|     main|m) git checkout -q "$MAIN";; |     config) init_config_action "$@";; | ||||||
|  |     main|m) checkout_main_action;; | ||||||
|     develop|dev|d) init_develop_action "$@";; |     develop|dev|d) init_develop_action "$@";; | ||||||
|     upstream|up|u) init_upstream_action "$@";; |     upstream|up|u) init_upstream_action "$@";; | ||||||
|     dist|x) init_dist_action "$@";; |     dist|x) init_dist_action "$@";; | ||||||
| @ -191,10 +259,11 @@ ConfigBranch= | |||||||
| ConfigFile= | ConfigFile= | ||||||
| action=init | action=init | ||||||
| Origin= | Origin= | ||||||
| Push=1 | [ -z "$PMAN_NO_PUSH" ] && Push=1 || Push= | ||||||
|  | ForceCreate= | ||||||
| args=( | args=( | ||||||
|     "gérer un projet git" |     "gérer un projet git" | ||||||
|     "repo|develop|upstream|dist |     "repo|config|develop|upstream|dist | ||||||
| 
 | 
 | ||||||
| INITIALISATION | INITIALISATION | ||||||
| 
 | 
 | ||||||
| @ -219,6 +288,8 @@ 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" | par défaut, utiliser le fichier .pman.conf dans le répertoire du dépôt s'il existe" | ||||||
|     -w,--show-config action=show "++\ |     -w,--show-config action=show "++\ | ||||||
| afficher la configuration chargée" | afficher la configuration chargée" | ||||||
|  |     --composer-select-profile action=composer_select_profile "\ | ||||||
|  | sélectionner le profil composer spécifié en argument" | ||||||
|     -O:,--origin Origin= "++\ |     -O:,--origin Origin= "++\ | ||||||
| origine vers laquelle pousser les branches" | origine vers laquelle pousser les branches" | ||||||
|     -n,--no-push Push= "\ |     -n,--no-push Push= "\ | ||||||
| @ -226,6 +297,8 @@ ne pas pousser les branches vers leur origine après leur création" | |||||||
|     --push Push=1 "++\ |     --push Push=1 "++\ | ||||||
| pousser les branches vers leur origine après leur création. | pousser les branches vers leur origine après leur création. | ||||||
| c'est l'option par défaut" | c'est l'option par défaut" | ||||||
|  |     -f,--force-create ForceCreate=1 "\ | ||||||
|  | Avec config, forcer la (re)création du fichier .pman.conf" | ||||||
| ) | ) | ||||||
| parse_args "$@"; set -- "${args[@]}" | parse_args "$@"; set -- "${args[@]}" | ||||||
| 
 | 
 | ||||||
| @ -244,6 +317,9 @@ init) | |||||||
|     git_ensure_cleancheckout |     git_ensure_cleancheckout | ||||||
|     init_action "$@" |     init_action "$@" | ||||||
|     ;; |     ;; | ||||||
|  | composer_select_profile) | ||||||
|  |     exec "$MYDIR/_pman-$action.php" "$@" | ||||||
|  |     ;; | ||||||
| *) | *) | ||||||
|     die "$action: action non implémentée" |     die "$action: action non implémentée" | ||||||
|     ;; |     ;; | ||||||
|  | |||||||
							
								
								
									
										79
									
								
								bin/prel
									
									
									
									
									
								
							
							
						
						
									
										79
									
								
								bin/prel
									
									
									
									
									
								
							| @ -42,6 +42,11 @@ function create_release_action() { | |||||||
|         merge_hotfix_action "$@"; return $? |         merge_hotfix_action "$@"; return $? | ||||||
|     fi |     fi | ||||||
| 
 | 
 | ||||||
|  |     [ -n "$ManualRelease" ] && ewarn "\ | ||||||
|  | L'option --no-merge a été forcée puisque ce dépôt ne supporte pas les releases automatiques" | ||||||
|  |     [ -z "$ShouldPush" ] && enote "\ | ||||||
|  | L'option --no-push a été forcée puisque ce dépôt n'a pas d'origine" | ||||||
|  | 
 | ||||||
|     if [ -z "$Version" -a -n "$CurrentVersion" -a -f VERSION.txt ]; then |     if [ -z "$Version" -a -n "$CurrentVersion" -a -f VERSION.txt ]; then | ||||||
|         Version="$(<VERSION.txt)" |         Version="$(<VERSION.txt)" | ||||||
|         Tag="$TAG_PREFIX$Version$TAG_SUFFIX" |         Tag="$TAG_PREFIX$Version$TAG_SUFFIX" | ||||||
| @ -80,6 +85,11 @@ Vous devrez: | |||||||
| # create | # create | ||||||
| if [ -n "\$create" ]; then | if [ -n "\$create" ]; then | ||||||
| esection "Création de la release" | esection "Création de la release" | ||||||
|  | EOF | ||||||
|  |     [ -n "$BEFORE_CREATE_RELEASE" ] && _scripta <<EOF | ||||||
|  | ( | ||||||
|  | $BEFORE_CREATE_RELEASE | ||||||
|  | )$or_die | ||||||
| EOF | EOF | ||||||
|     _rscript_create_release_branch |     _rscript_create_release_branch | ||||||
|     [ -n "$AFTER_CREATE_RELEASE" ] && _scripta <<EOF |     [ -n "$AFTER_CREATE_RELEASE" ] && _scripta <<EOF | ||||||
| @ -96,6 +106,11 @@ EOF | |||||||
| # merge | # merge | ||||||
| if [ -n "\$merge" ]; then | if [ -n "\$merge" ]; then | ||||||
| esection "Fusionner la release" | esection "Fusionner la release" | ||||||
|  | EOF | ||||||
|  |     [ -n "$BEFORE_MERGE_RELEASE" ] && _scripta <<EOF | ||||||
|  | ( | ||||||
|  | $BEFORE_MERGE_RELEASE | ||||||
|  | )$or_die | ||||||
| EOF | EOF | ||||||
|     _rscript_merge_release_branch "$DestBranch" "$Tag" |     _rscript_merge_release_branch "$DestBranch" "$Tag" | ||||||
|     _rscript_merge_release_branch "$SrcBranch" |     _rscript_merge_release_branch "$SrcBranch" | ||||||
| @ -114,6 +129,11 @@ EOF | |||||||
| # push | # push | ||||||
| if [ -n "\$push" ]; then | if [ -n "\$push" ]; then | ||||||
| esection "Pousser branches et tags" | esection "Pousser branches et tags" | ||||||
|  | EOF | ||||||
|  |     [ -n "$BEFORE_PUSH_RELEASE" ] && _scripta <<EOF | ||||||
|  | ( | ||||||
|  | $BEFORE_PUSH_RELEASE | ||||||
|  | )$or_die | ||||||
| EOF | EOF | ||||||
|     _script_push_branches |     _script_push_branches | ||||||
|     _script_push_tags |     _script_push_tags | ||||||
| @ -126,26 +146,25 @@ EOF | |||||||
| fi | fi | ||||||
| EOF | EOF | ||||||
| 
 | 
 | ||||||
|     [ -n "$Merge" ] && Merged=1 || Merged= |     [ -z "$ManualRelease" -a -n "$Merge" ] && ShouldMerge= || ShouldMerge=1 | ||||||
|     [ -n "$Push" -o "$CantPush" ] && Pushed=1 || Pushed= |     [ -n "$ShouldPush" -a -n "$Push" ] && ShouldPush= | ||||||
|     if [ -n "$_NoRunScript" ]; then |     if [ -n "$_Fake" ]; then | ||||||
|         einfo "Veuillez consulter le script $script pour le détail des opérations à effectuer" |         cat "$script" | ||||||
|     elif ! "$script" create ${Merge:+merge} ${Push:+push}; then |     elif ! "$script" create ${Merge:+merge} ${Push:+push}; then | ||||||
|         eimportant "\ |         eimportant "\ | ||||||
| Le script $script a été lancé avec les arguments 'create${Merge:+ merge}${Push:+ push}' | Le script $script a été lancé avec les arguments 'create${Merge:+ merge}${Push:+ push}' | ||||||
| Veuillez le consulter pour le détail des opérations qui n'ont pas pu êtres effectuées" | En cas d'erreur de merge, veuillez corriger les erreurs puis continuer avec | ||||||
|  |     git merge --continue | ||||||
|  | Veuillez aussi consulter le script et/ou le relancer | ||||||
|  |     ./$script${Push:+ push}" | ||||||
|         die |         die | ||||||
|     elif [ -n "$Merged" -a -n "$Pushed" ]; then |     elif [ -n "$Merge" -a -n "$Push" ]; then | ||||||
|         [ -n "$_KeepScript" ] || rm "$script" |         [ -n "$_KeepScript" ] || rm "$script" | ||||||
|     else |     else | ||||||
|         local cmd |  | ||||||
|         [ -n "$Merged" ] || cmd="$cmd |  | ||||||
|     ./$script merge" |  | ||||||
|         [ -n "$Pushed" ] || cmd="$cmd |  | ||||||
|     ./$script push" |  | ||||||
|         einfo "\ |         einfo "\ | ||||||
| Le script $script a été lancé avec les arguments 'create${Merge:+ merge}${Push:+ push}' | Le script $script a été lancé avec les arguments 'create${Merge:+ merge}${Push:+ push}' | ||||||
| Veuillez le consulter pour le détail des autres opérations à effectuer$cmd" | Vous pouvez consulter le script et/ou le relancer | ||||||
|  |     ./$script${ShouldMerge:+ merge}${ShouldPush:+ push}" | ||||||
|     fi |     fi | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -172,8 +191,8 @@ chdir= | |||||||
| Origin= | Origin= | ||||||
| ConfigBranch= | ConfigBranch= | ||||||
| ConfigFile= | ConfigFile= | ||||||
|  | _Fake= | ||||||
| _KeepScript= | _KeepScript= | ||||||
| _NoRunScript= |  | ||||||
| action=release | action=release | ||||||
| [ -z "$PMAN_NO_MERGE" ] && Merge=1 || Merge= | [ -z "$PMAN_NO_MERGE" ] && Merge=1 || Merge= | ||||||
| [ -z "$PMAN_NO_PUSH" ] && Push=1 || Push= | [ -z "$PMAN_NO_PUSH" ] && Push=1 || Push= | ||||||
| @ -182,7 +201,17 @@ CurrentVersion= | |||||||
| ForceCreate= | ForceCreate= | ||||||
| args=( | args=( | ||||||
|     "faire une nouvelle release à partir de la branche source" |     "faire une nouvelle release à partir de la branche source" | ||||||
|     " -v VERSION [source]" |     " -v VERSION [source] | ||||||
|  | 
 | ||||||
|  | CONFIGURATION | ||||||
|  | Le fichier .pman.conf contient la configuration des branches. Les variables | ||||||
|  | supplémentaires suivantes peuvent être définies: | ||||||
|  |     BEFORE_CREATE_RELEASE | ||||||
|  |     AFTER_CREATE_RELEASE | ||||||
|  |     BEFORE_MERGE_RELEASE | ||||||
|  |     AFTER_MERGE_RELEASE | ||||||
|  |     BEFORE_PUSH_RELEASE | ||||||
|  |     AFTER_PUSH_RELEASE" | ||||||
|     -d:,--chdir:BASEDIR chdir= "répertoire dans lequel se placer avant de lancer les opérations" |     -d:,--chdir:BASEDIR chdir= "répertoire dans lequel se placer avant de lancer les opérations" | ||||||
|     -O:,--origin Origin= "++\ |     -O:,--origin Origin= "++\ | ||||||
| origine à partir de laquelle les branches distantes sont considérées" | origine à partir de laquelle les branches distantes sont considérées" | ||||||
| @ -191,8 +220,8 @@ branche à partir de laquelle charger la configuration" | |||||||
|     -c:,--config-file:CONFIG ConfigFile= "++\ |     -c:,--config-file:CONFIG ConfigFile= "++\ | ||||||
| fichier de configuration des branches. cette option est prioritaire sur --config-branch | fichier de configuration des branches. cette option est prioritaire sur --config-branch | ||||||
| par défaut, utiliser le fichier .pman.conf dans le répertoire du dépôt s'il existe" | 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" |     --keep-script _KeepScript=1 "++option non documentée" | ||||||
|     --no-run-script _NoRunScript=1 "++option non documentée" |  | ||||||
|     -w,--show action=show "\ |     -w,--show action=show "\ | ||||||
| lister les modifications qui seraient intégrées dans la release" | lister les modifications qui seraient intégrées dans la release" | ||||||
|     --release action=release "++\ |     --release action=release "++\ | ||||||
| @ -208,11 +237,11 @@ ne pas pousser les branches vers leur origine après la création de la release" | |||||||
|     --push Push=1 "++\ |     --push Push=1 "++\ | ||||||
| pousser les branches vers leur origine après la création de la release. | pousser les branches vers leur origine après la création de la release. | ||||||
| c'est l'option par défaut" | c'est l'option par défaut" | ||||||
|     -v:,--version Version= "\ |     -v:,--version:VERSION Version= "\ | ||||||
| spécifier la version de la release à créer" | spécifier la version de la release à créer" | ||||||
|     -C,--current-version CurrentVersion=1 "++\ |     -C,--current-version CurrentVersion=1 "++\ | ||||||
| si aucune version n'est spécifiée, prendre la version présente dans le fichier VERSION.txt" | si aucune version n'est spécifiée, prendre la version présente dans le fichier VERSION.txt" | ||||||
|     -f:,--force-create ForceCreate= "\ |     -f,--force-create ForceCreate=1 "\ | ||||||
| forcer la création de la release même si le tag correspond à la version existe déjà" | forcer la création de la release même si le tag correspond à la version existe déjà" | ||||||
| ) | ) | ||||||
| parse_args "$@"; set -- "${args[@]}" | parse_args "$@"; set -- "${args[@]}" | ||||||
| @ -223,19 +252,11 @@ load_branches all | |||||||
| load_config "$MYNAME" | load_config "$MYNAME" | ||||||
| load_branches current "$1"; shift | load_branches current "$1"; shift | ||||||
| 
 | 
 | ||||||
| if [ -n "$Merge" -a -n "$NOAUTO" ]; then | [ -n "$Merge" -a -n "$NOAUTO" ] && ManualRelease=1 || ManualRelease= | ||||||
|     ewarn "L'option --no-merge a été forcée puisque ce dépôt ne supporte pas les releases automatiques" | [ -n "$ManualRelease" ] && Merge= | ||||||
|     Merge= |  | ||||||
| fi |  | ||||||
| [ -z "$Merge" ] && Push= | [ -z "$Merge" ] && Push= | ||||||
| 
 | 
 | ||||||
| CantPush= | resolve_should_push quiet | ||||||
| [ -n "$Origin" ] || Origin=origin |  | ||||||
| if ! git_have_remote "$Origin" && [ -n "$Push" ]; then |  | ||||||
|     ewarn "L'option --no-push a été forcée puisque ce dépôt n'a pas d'origine" |  | ||||||
|     CantPush=1 |  | ||||||
| fi |  | ||||||
| [ -n "$CantPush" ] && Push= |  | ||||||
| 
 | 
 | ||||||
| # puis faire l'action que l'on nous demande | # puis faire l'action que l'on nous demande | ||||||
| case "$action" in | case "$action" in | ||||||
| @ -245,7 +266,7 @@ show) | |||||||
|     show_action "$@" |     show_action "$@" | ||||||
|     ;; |     ;; | ||||||
| release) | release) | ||||||
|     git_ensure_cleancheckout |     [ -z "$_Fake" ] && git_ensure_cleancheckout | ||||||
|     ensure_branches |     ensure_branches | ||||||
|     case "$SrcType" in |     case "$SrcType" in | ||||||
|     release) merge_release_action "$@";; |     release) merge_release_action "$@";; | ||||||
|  | |||||||
							
								
								
									
										60
									
								
								bin/pwip
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										60
									
								
								bin/pwip
									
									
									
									
									
										Executable file
									
								
							| @ -0,0 +1,60 @@ | |||||||
|  | #!/bin/bash | ||||||
|  | # -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8 | ||||||
|  | source "$(dirname -- "$0")/../load.sh" || exit 1 | ||||||
|  | require: git pman pman.conf | ||||||
|  | 
 | ||||||
|  | git_cleancheckout_DIRTY="\ | ||||||
|  | Vous avez des modifications locales. | ||||||
|  | Enregistrez ces modifications avant de créer une nouvelle branche" | ||||||
|  | 
 | ||||||
|  | chdir= | ||||||
|  | Origin= | ||||||
|  | ConfigBranch= | ||||||
|  | ConfigFile= | ||||||
|  | [ -z "$PMAN_NO_PUSH" ] && Push=1 || Push= | ||||||
|  | args=( | ||||||
|  |     "créer une branche de feature" | ||||||
|  |     "<feature>" | ||||||
|  |     -d:,--chdir:BASEDIR chdir= "répertoire dans lequel se placer avant de lancer les opérations" | ||||||
|  |     -O:,--origin Origin= "++\ | ||||||
|  | origine à partir de laquelle les branches distantes sont considérées" | ||||||
|  |     -B:,--config-branch ConfigBranch= "++\ | ||||||
|  | branche à partir de laquelle charger la configuration" | ||||||
|  |     -c:,--config-file:CONFIG ConfigFile= "++\ | ||||||
|  | fichier de configuration des branches. cette option est prioritaire sur --config-branch | ||||||
|  | par défaut, utiliser le fichier .pman.conf dans le répertoire du dépôt s'il existe" | ||||||
|  |     -n,--no-push Push= "\ | ||||||
|  | ne pas pousser les branches vers leur origine après la fusion" | ||||||
|  |     --push Push=1 "++\ | ||||||
|  | pousser les branches vers leur origine après la fusion. | ||||||
|  | c'est l'option par défaut" | ||||||
|  | ) | ||||||
|  | parse_args "$@"; set -- "${args[@]}" | ||||||
|  | 
 | ||||||
|  | # charger la configuration | ||||||
|  | ensure_gitdir "$chdir" | ||||||
|  | load_branches all | ||||||
|  | load_config "$MYNAME" | ||||||
|  | load_branches current | ||||||
|  | 
 | ||||||
|  | branch="$1" | ||||||
|  | if [ -z "$branch" -a ${#FeatureBranches[*]} -eq 1 ]; then | ||||||
|  |     branch="${FeatureBranches[0]}" | ||||||
|  | fi | ||||||
|  | [ -n "$branch" ] || die "Vous devez spécifier la branche à créer" | ||||||
|  | branch="$FEATURE${branch#$FEATURE}" | ||||||
|  | 
 | ||||||
|  | resolve_should_push | ||||||
|  | git_ensure_cleancheckout | ||||||
|  | 
 | ||||||
|  | if array_contains AllBranches "$branch"; then | ||||||
|  |     git checkout -q "$branch" | ||||||
|  | else | ||||||
|  |     # si la branche source n'existe pas, la créer | ||||||
|  |     args=(--origin "$Origin") | ||||||
|  |     if [ -n "$ConfigFile" ]; then args+=(--config-file "$ConfigFile") | ||||||
|  |     elif [ -n "$ConfigBranch" ]; then args+=(--config-branch "$ConfigBranch") | ||||||
|  |     fi | ||||||
|  |     [ -z "$Push" ] && args+=(--no-push) | ||||||
|  |     exec "$MYDIR/pman" "${args[@]}" "$branch" | ||||||
|  | fi | ||||||
| @ -25,7 +25,7 @@ COPY --from=builder /src/su-exec/su-exec /g/ | |||||||
| RUN /g/build | RUN /g/build | ||||||
| 
 | 
 | ||||||
| COPY --from=php /g/ /g/ | COPY --from=php /g/ /g/ | ||||||
| RUN /g/build -a @apache-php-cas php-utils | RUN /g/build -a @php-apache-cas php-utils | ||||||
| 
 | 
 | ||||||
| EXPOSE 80 443 | EXPOSE 80 443 | ||||||
| ENTRYPOINT ["/g/entrypoint"] | ENTRYPOINT ["/g/entrypoint"] | ||||||
|  | |||||||
| @ -34,7 +34,7 @@ COPY --from=legacytools /g/ /g/ | |||||||
| RUN /g/build nutools | RUN /g/build nutools | ||||||
| 
 | 
 | ||||||
| COPY --from=php /g/ /g/ | COPY --from=php /g/ /g/ | ||||||
| RUN /g/build -a @apache-php-cas php-utils | RUN /g/build -a @php-apache-cas php-utils | ||||||
| 
 | 
 | ||||||
| COPY --from=instantclient /g/ /g/ | COPY --from=instantclient /g/ /g/ | ||||||
| COPY --from=builder /opt/oracle/ /opt/oracle/ | COPY --from=builder /opt/oracle/ /opt/oracle/ | ||||||
|  | |||||||
| @ -610,6 +610,42 @@ class cl { | |||||||
| 
 | 
 | ||||||
|   #############################################################################
 |   #############################################################################
 | ||||||
| 
 | 
 | ||||||
|  |   /** | ||||||
|  |    * tester si $array a en début de tableau les mêmes clés que $ref, et dans le | ||||||
|  |    * même ordre. $array peut avoir d'autres clés, ça n'influe pas sur le résultat | ||||||
|  |    * | ||||||
|  |    * $keys obtient la liste des clés de $ref trouvées, dans l'ordre de $array | ||||||
|  |    * $remainKeys obtient la liste des clés de $array qui ne sont pas dans $ref | ||||||
|  |    * $missingKeys obtient la liste des clés de $ref qui ne sont pas dans $array | ||||||
|  |    */ | ||||||
|  |   static function same_keys(?array $array, ?array $ref, ?array &$keys=null, ?array &$remainKeys=null, ?array &$missingKeys=null): bool { | ||||||
|  |     $keys = []; | ||||||
|  |     $remainKeys = []; | ||||||
|  |     $missingKeys = []; | ||||||
|  |     if ($array === null || $array === []) { | ||||||
|  |       if ($ref === null || $ref === []) return true; | ||||||
|  |       $missingKeys = array_keys($ref); | ||||||
|  |       return false; | ||||||
|  |     } elseif ($ref === null || $ref === []) { | ||||||
|  |       $remainKeys = array_keys($array); | ||||||
|  |       return true; | ||||||
|  |     } | ||||||
|  |     $refKeys = array_keys($ref); | ||||||
|  |     $refCount = count($ref); | ||||||
|  |     $index = 0; | ||||||
|  |     $sameKeys = true; | ||||||
|  |     foreach (array_keys($array) as $key) { | ||||||
|  |       if ($index < $refCount) { | ||||||
|  |         if ($key !== $refKeys[$index]) $sameKeys = false; | ||||||
|  |         $index++; | ||||||
|  |       } | ||||||
|  |       if (array_key_exists($key, $ref)) $keys[] = $key; | ||||||
|  |       else $remainKeys[] = $key; | ||||||
|  |     } | ||||||
|  |     $missingKeys = array_values(array_diff($refKeys, $keys)); | ||||||
|  |     return $sameKeys && $index == $refCount; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|   /** |   /** | ||||||
|    * retourner le tableau $array en "renommant" les clés selon le tableau |    * retourner le tableau $array en "renommant" les clés selon le tableau | ||||||
|    * $mappings qui contient des associations de la forme [$from => $to] |    * $mappings qui contient des associations de la forme [$from => $to] | ||||||
|  | |||||||
| @ -2,7 +2,6 @@ | |||||||
| namespace nulib\ext; | namespace nulib\ext; | ||||||
| 
 | 
 | ||||||
| use Exception; | use Exception; | ||||||
| use nulib\ext\json\JsonException; |  | ||||||
| use nulib\file; | use nulib\file; | ||||||
| use nulib\os\IOException; | use nulib\os\IOException; | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -6,7 +6,7 @@ class ref_schema { | |||||||
|   const NATURE_METASCHEMA = [ |   const NATURE_METASCHEMA = [ | ||||||
|     "nature" => ["string", null, "nature du schéma", |     "nature" => ["string", null, "nature du schéma", | ||||||
|       "pkey" => 0, |       "pkey" => 0, | ||||||
|       "allowed_values" => ["assoc", "list", "scalar"], |       "allowed_values" => ["scalar", "assoc", "list"], | ||||||
|     ], |     ], | ||||||
|     "title" => ["?string", null, "libellé de la valeur"], |     "title" => ["?string", null, "libellé de la valeur"], | ||||||
|     "required" => ["bool", false, "la valeur est-elle requise?"], |     "required" => ["bool", false, "la valeur est-elle requise?"], | ||||||
| @ -31,9 +31,10 @@ class ref_schema { | |||||||
|     "messages" => ["?array", null, "messages à afficher en cas d'erreur d'analyse"], |     "messages" => ["?array", null, "messages à afficher en cas d'erreur d'analyse"], | ||||||
|     "formatter_func" => ["?callable", null, "fonction qui formatte la valeur pour affichage"], |     "formatter_func" => ["?callable", null, "fonction qui formatte la valeur pour affichage"], | ||||||
|     "format" => [null, null, "format à utiliser pour l'affichage"], |     "format" => [null, null, "format à utiliser pour l'affichage"], | ||||||
|     "" => ["array", "scalar", "nature du schéma", |     "" => ["array", ["scalar"], "nature du schéma", | ||||||
|       "" => ["assoc", "schema" => self::NATURE_METASCHEMA], |       "schema" => self::NATURE_METASCHEMA, | ||||||
|     ], |     ], | ||||||
|  |     "schema" => ["?array", null, "schéma de la valeur si c'est un array"], | ||||||
|     "name" => ["?string", null, "identifiant de la valeur"], |     "name" => ["?string", null, "identifiant de la valeur"], | ||||||
|     "pkey" => ["?pkey", null, "chemin de clé de la valeur dans un tableau associatif"], |     "pkey" => ["?pkey", null, "chemin de clé de la valeur dans un tableau associatif"], | ||||||
|     "header" => ["?string", null, "nom de l'en-tête s'il faut présenter cette donnée dans un tableau"], |     "header" => ["?string", null, "nom de l'en-tête s'il faut présenter cette donnée dans un tableau"], | ||||||
|  | |||||||
| @ -6,5 +6,6 @@ class ref_types { | |||||||
|     "boolean" => "bool", |     "boolean" => "bool", | ||||||
|     "integer" => "int", |     "integer" => "int", | ||||||
|     "flt" => "float", "double" => "float", "dbl" => "float", |     "flt" => "float", "double" => "float", "dbl" => "float", | ||||||
|  |     "func" => "callable", "function" => "callable", | ||||||
|   ]; |   ]; | ||||||
| } | } | ||||||
|  | |||||||
							
								
								
									
										172
									
								
								php/src/tools/pman/ComposerFile.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										172
									
								
								php/src/tools/pman/ComposerFile.php
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,172 @@ | |||||||
|  | <?php | ||||||
|  | namespace nulib\tools\pman; | ||||||
|  | 
 | ||||||
|  | use nulib\cl; | ||||||
|  | use nulib\ext\json; | ||||||
|  | use nulib\file; | ||||||
|  | use nulib\os\path; | ||||||
|  | use nulib\ValueException; | ||||||
|  | 
 | ||||||
|  | class ComposerFile { | ||||||
|  |   function __construct(string $composerFile=".", bool $ensureExists=true) { | ||||||
|  |     if (is_dir($composerFile)) $composerFile = path::join($composerFile, 'composer.json'); | ||||||
|  |     if ($ensureExists && !file_exists($composerFile)) { | ||||||
|  |       $message = path::ppath($composerFile).": fichier introuvable"; | ||||||
|  |       throw new ValueException($message); | ||||||
|  |     } | ||||||
|  |     $this->composerFile = $composerFile; | ||||||
|  |     $this->load(); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   protected string $composerFile; | ||||||
|  | 
 | ||||||
|  |   function getComposerFile(): string { | ||||||
|  |     return $this->composerFile; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   protected ?array $data = null; | ||||||
|  | 
 | ||||||
|  |   protected function load(): array { | ||||||
|  |     if ($this->data === null) { | ||||||
|  |       $this->data = json::load($this->composerFile); | ||||||
|  |     } | ||||||
|  |     return $this->data; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   function getv(string $pkey="", $default=null) { | ||||||
|  |     return cl::pget($this->data, $pkey, $default); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   function geta(string $pkey="", ?array $default=[]): ?array { | ||||||
|  |     return cl::withn($this->getv($pkey, $default)); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   function getRequires(): array { | ||||||
|  |     return $this->geta("require"); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   function setRequire(string $dep, string $version): void { | ||||||
|  |     $this->setPkey("require.$dep", $version); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   function getRequireDevs(): array { | ||||||
|  |     return $this->geta("require-dev"); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   function setRequireDev(string $dep, string $version): void { | ||||||
|  |     $this->setPkey("require-dev.$dep", $version); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   function getRepositories(): array { | ||||||
|  |     return $this->geta("repositories"); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   function setRepositories(array $repositories): void { | ||||||
|  |     $this->data["repositories"] = $repositories; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   function setPkey(string $pkey, $value): void { | ||||||
|  |     cl::pset($this->data, $pkey, $value); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   function delPkey(string $pkey): void { | ||||||
|  |     cl::pdel($this->data, $pkey); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   const PATHS = [ | ||||||
|  |     "nulib/php" => "nulib", | ||||||
|  |   ]; | ||||||
|  | 
 | ||||||
|  |   function selectProfile(string $profile, PmanYamlConfigFile $config): void { | ||||||
|  |     $config = $config->getProfileConfig($profile); | ||||||
|  |     // corriger les liens
 | ||||||
|  |     $deps = cl::merge(array_keys($config["require"]), array_keys($config["require-dev"])); | ||||||
|  |     $paths = []; | ||||||
|  |     foreach ($deps as $dep) { | ||||||
|  |       $path = cl::get(self::PATHS, $dep, $dep); | ||||||
|  |       $path = str_replace("/", "-", $path); | ||||||
|  |       $path = "../$path"; | ||||||
|  |       $paths[$dep] = $path; | ||||||
|  |     } | ||||||
|  |     if ($config["link"]) { | ||||||
|  |       // Ajouter les liens
 | ||||||
|  |       $adds = []; | ||||||
|  |       $repositories = $this->getRepositories(); | ||||||
|  |       foreach ($deps as $dep) { | ||||||
|  |         $found = false; | ||||||
|  |         foreach ($repositories as $repository) { | ||||||
|  |           if ($repository["type"] === "path" && $repository["url"] === $paths[$dep]) { | ||||||
|  |             $found = true; | ||||||
|  |             break; | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |         if (!$found) { | ||||||
|  |           $adds[] = [ | ||||||
|  |             "type" => "path", | ||||||
|  |             "url" => $paths[$dep], | ||||||
|  |           ]; | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |       if ($adds) { | ||||||
|  |         $this->setRepositories(cl::merge($adds, $repositories)); | ||||||
|  |       } | ||||||
|  |     } else { | ||||||
|  |       // Supprimer les liens
 | ||||||
|  |       $dels = []; | ||||||
|  |       $repositories = $this->getRepositories(); | ||||||
|  |       foreach ($deps as $dep) { | ||||||
|  |         foreach ($repositories as $key => $repository) { | ||||||
|  |           if ($repository["type"] === "path" && $repository["url"] === $paths[$dep]) { | ||||||
|  |             $dels[] = $key; | ||||||
|  |             break; | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |       if ($dels) { | ||||||
|  |         foreach (array_reverse($dels) as $key) { | ||||||
|  |           unset($repositories[$key]); | ||||||
|  |         } | ||||||
|  |         $this->setRepositories(array_values($repositories)); | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |     // corriger les versions
 | ||||||
|  |     foreach ($config["require"] as $dep => $version) { | ||||||
|  |       $this->data["require"][$dep] = $version; | ||||||
|  |     } | ||||||
|  |     foreach ($config["require-dev"] as $dep => $version) { | ||||||
|  |       $this->data["require-dev"][$dep] = $version; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   function getLocalDeps(): array { | ||||||
|  |     $deps = cl::merge(array_keys($this->getRequires()), array_keys($this->getRequireDevs())); | ||||||
|  |     $paths = []; | ||||||
|  |     foreach ($deps as $dep) { | ||||||
|  |       $path = cl::get(self::PATHS, $dep, $dep); | ||||||
|  |       $path = str_replace("/", "-", $path); | ||||||
|  |       $path = "../$path"; | ||||||
|  |       $paths[$dep] = $path; | ||||||
|  |     } | ||||||
|  |     $repositories = $this->getRepositories(); | ||||||
|  |     $localDeps = []; | ||||||
|  |     foreach ($deps as $dep) { | ||||||
|  |       foreach ($repositories as $key => $repository) { | ||||||
|  |         if ($repository["type"] === "path" && $repository["url"] === $paths[$dep]) { | ||||||
|  |           $localDeps[$dep] = $repository["url"]; | ||||||
|  |           break; | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |     return $localDeps; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   function print(): void { | ||||||
|  |     $contents = json::with($this->data, json::INDENT_TABS); | ||||||
|  |     if ($contents) echo "$contents\n"; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   function write(): void { | ||||||
|  |     $contents = json::with($this->data, json::INDENT_TABS); | ||||||
|  |     file::writer($this->composerFile)->putContents("$contents\n"); | ||||||
|  |   } | ||||||
|  | } | ||||||
							
								
								
									
										57
									
								
								php/src/tools/pman/PmanYamlConfigFile.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								php/src/tools/pman/PmanYamlConfigFile.php
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,57 @@ | |||||||
|  | <?php | ||||||
|  | namespace nulib\tools\pman; | ||||||
|  | 
 | ||||||
|  | use nulib\A; | ||||||
|  | use nulib\ext\yaml; | ||||||
|  | use nulib\os\path; | ||||||
|  | use nulib\ValueException; | ||||||
|  | 
 | ||||||
|  | class PmanYamlConfigFile { | ||||||
|  |   function __construct(string $configFile=".", bool $ensureExists=true) { | ||||||
|  |     if (is_dir($configFile)) $configFile = path::join($configFile, '.pman.yml'); | ||||||
|  |     if ($ensureExists && !file_exists($configFile)) { | ||||||
|  |       $message = path::ppath($configFile).": fichier introuvable"; | ||||||
|  |       throw new ValueException($message); | ||||||
|  |     } | ||||||
|  |     $this->configFile = $configFile; | ||||||
|  |     $this->load(); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   protected string $configFile; | ||||||
|  | 
 | ||||||
|  |   function getConfigFile(): string { | ||||||
|  |     return $this->configFile; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   protected ?array $data = null; | ||||||
|  | 
 | ||||||
|  |   protected function load(): array { | ||||||
|  |     if ($this->data === null) { | ||||||
|  |       $data = yaml::load($this->configFile); | ||||||
|  |       $composer =& $data["composer"]; | ||||||
|  |       A::ensure_array($composer); | ||||||
|  |       A::ensure_array($composer["profiles"]); | ||||||
|  |       foreach ($composer["profiles"] as $profileName) { | ||||||
|  |         $profile =& $composer[$profileName]; | ||||||
|  |         A::ensure_array($profile); | ||||||
|  |         $profile["link"] = boolval($profile["link"] ?? false); | ||||||
|  |         A::ensure_array($profile["require"]); | ||||||
|  |         A::ensure_array($profile["require-dev"]); | ||||||
|  |       } | ||||||
|  |       $this->data = $data; | ||||||
|  |     } | ||||||
|  |     return $this->data; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   function getProfileConfig(string $profile): array { | ||||||
|  |     $config = $this->data["composer"][$profile] ?? null; | ||||||
|  |     if ($config === null) { | ||||||
|  |       throw new ValueException("$profile: profil invalide"); | ||||||
|  |     } | ||||||
|  |     return $config; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   function print(): void { | ||||||
|  |     yaml::dump($this->data); | ||||||
|  |   } | ||||||
|  | } | ||||||
							
								
								
									
										37
									
								
								php/tests/clTest.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								php/tests/clTest.php
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,37 @@ | |||||||
|  | <?php | ||||||
|  | namespace nulib; | ||||||
|  | 
 | ||||||
|  | use nulib\tests\TestCase; | ||||||
|  | 
 | ||||||
|  | class clTest extends TestCase { | ||||||
|  |   function checkKeys(?array $array, ?array $ref, bool $sameKeys, array $expectedKeys, array $expectedRemains, array $expectedMissings): void { | ||||||
|  |     self::assertSame($sameKeys, cl::same_keys($array, $ref, $keys, $remains, $missings), "sameKeys"); | ||||||
|  |     self::assertSame($expectedKeys, $keys, "keys"); | ||||||
|  |     self::assertSame($expectedRemains, $remains, "remains"); | ||||||
|  |     self::assertSame($expectedMissings, $missings, "missings"); | ||||||
|  |   } | ||||||
|  |   function test_same_keys() { | ||||||
|  |     $array = ["a" => 42, "b" => "tesxt"]; $arrayKeys = array_keys($array); | ||||||
|  |     $xarray = ["parasite0", "a" => 42, "parasite1", "b" => "tesxt"]; $xarrayKeys = array_keys($array); | ||||||
|  |     $ref = ["a" => "int", "b" => "text"]; $refKeys = array_keys($ref); | ||||||
|  |     $missingArray = ["c" => true]; $missingKeys = array_keys($missingArray); | ||||||
|  |     $missingRef = ["c" => "bool"]; $missingKeys = array_keys($missingRef); | ||||||
|  | 
 | ||||||
|  |     $this->checkKeys(null, null, true, [], [], []); | ||||||
|  |     $this->checkKeys(null, [], true, [], [], []); | ||||||
|  |     $this->checkKeys([], null, true, [], [], []); | ||||||
|  |     $this->checkKeys([], [], true, [], [], []); | ||||||
|  | 
 | ||||||
|  |     $this->checkKeys(null, $ref, false, [], [], $refKeys); | ||||||
|  |     $this->checkKeys([], $ref, false, [], [], $refKeys); | ||||||
|  | 
 | ||||||
|  |     $this->checkKeys($array, null, true, [], $arrayKeys, []); | ||||||
|  |     $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($xarray, $ref, false, $arrayKeys, [0, 1], []); | ||||||
|  |   } | ||||||
|  | } | ||||||
| @ -1,67 +0,0 @@ | |||||||
| <?php |  | ||||||
| namespace nulib\php\access; |  | ||||||
| 
 |  | ||||||
| use nulib\tests\TestCase; |  | ||||||
| use nulib\wip\php\access\KeyAccess; |  | ||||||
| use stdClass; |  | ||||||
| 
 |  | ||||||
| class KeyAccessTest extends TestCase { |  | ||||||
|   function testAccess() { |  | ||||||
|     $default = new stdClass(); |  | ||||||
|     $array = ["null" => null, "false" => false, "empty" => ""]; |  | ||||||
| 
 |  | ||||||
|     #
 |  | ||||||
|     $a = new KeyAccess($array, "inexistant"); |  | ||||||
|     self::assertFalse($a->exists()); |  | ||||||
|     self::assertFalse($a->available()); |  | ||||||
|     self::assertSame($default, $a->get($default)); |  | ||||||
| 
 |  | ||||||
|     $a = new KeyAccess($array, "null"); |  | ||||||
|     self::assertTrue($a->exists()); |  | ||||||
|     self::assertTrue($a->available()); |  | ||||||
|     self::assertSame(null, $a->get($default)); |  | ||||||
| 
 |  | ||||||
|     $a = new KeyAccess($array, "false"); |  | ||||||
|     self::assertTrue($a->exists()); |  | ||||||
|     self::assertFalse($a->available()); |  | ||||||
|     self::assertSame($default, $a->get($default)); |  | ||||||
| 
 |  | ||||||
|     $a = new KeyAccess($array, "empty"); |  | ||||||
|     self::assertTrue($a->exists()); |  | ||||||
|     self::assertTrue($a->available()); |  | ||||||
|     self::assertSame("", $a->get($default)); |  | ||||||
| 
 |  | ||||||
|     #
 |  | ||||||
|     $a = new KeyAccess($array, "null", ["allow_null" => false]); |  | ||||||
|     self::assertTrue($a->exists()); |  | ||||||
|     self::assertFalse($a->available()); |  | ||||||
|     self::assertSame($default, $a->get($default)); |  | ||||||
| 
 |  | ||||||
|     $a = new KeyAccess($array, "null", ["allow_null" => true]); |  | ||||||
|     self::assertTrue($a->exists()); |  | ||||||
|     self::assertTrue($a->available()); |  | ||||||
|     self::assertSame(null, $a->get($default)); |  | ||||||
| 
 |  | ||||||
|     #
 |  | ||||||
|     $a = new KeyAccess($array, "false", ["allow_false" => false]); |  | ||||||
|     self::assertTrue($a->exists()); |  | ||||||
|     self::assertFalse($a->available()); |  | ||||||
|     self::assertSame($default, $a->get($default)); |  | ||||||
| 
 |  | ||||||
|     $a = new KeyAccess($array, "false", ["allow_false" => true]); |  | ||||||
|     self::assertTrue($a->exists()); |  | ||||||
|     self::assertTrue($a->available()); |  | ||||||
|     self::assertSame(false, $a->get($default)); |  | ||||||
| 
 |  | ||||||
|     #
 |  | ||||||
|     $a = new KeyAccess($array, "empty", ["allow_empty" => false]); |  | ||||||
|     self::assertTrue($a->exists()); |  | ||||||
|     self::assertFalse($a->available()); |  | ||||||
|     self::assertSame($default, $a->get($default)); |  | ||||||
| 
 |  | ||||||
|     $a = new KeyAccess($array, "empty", ["allow_empty" => true]); |  | ||||||
|     self::assertTrue($a->exists()); |  | ||||||
|     self::assertTrue($a->available()); |  | ||||||
|     self::assertSame("", $a->get($default)); |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| @ -1,70 +0,0 @@ | |||||||
| <?php |  | ||||||
| namespace nulib\php\access; |  | ||||||
| 
 |  | ||||||
| use nulib\tests\TestCase; |  | ||||||
| use nulib\wip\php\access\ValueAccess; |  | ||||||
| use stdClass; |  | ||||||
| 
 |  | ||||||
| class ValueAccessTest extends TestCase { |  | ||||||
|   function testAccess() { |  | ||||||
|     $default = new stdClass(); |  | ||||||
| 
 |  | ||||||
|     #
 |  | ||||||
|     $i = null; |  | ||||||
|     $a = new ValueAccess($i); |  | ||||||
|     self::assertFalse($a->exists()); |  | ||||||
|     self::assertFalse($a->available()); |  | ||||||
|     self::assertSame($default, $a->get($default)); |  | ||||||
| 
 |  | ||||||
|     $i = false; |  | ||||||
|     $a = new ValueAccess($i); |  | ||||||
|     self::assertTrue($a->exists()); |  | ||||||
|     self::assertTrue($a->available()); |  | ||||||
|     self::assertSame(false, $a->get($default)); |  | ||||||
| 
 |  | ||||||
|     $i = ""; |  | ||||||
|     $a = new ValueAccess($i); |  | ||||||
|     self::assertTrue($a->exists()); |  | ||||||
|     self::assertTrue($a->available()); |  | ||||||
|     self::assertSame("", $a->get($default)); |  | ||||||
| 
 |  | ||||||
|     #
 |  | ||||||
|     $i = null; |  | ||||||
|     $a = new ValueAccess($i, ["allow_null" => false]); |  | ||||||
|     self::assertFalse($a->exists()); |  | ||||||
|     self::assertFalse($a->available()); |  | ||||||
|     self::assertSame($default, $a->get($default)); |  | ||||||
| 
 |  | ||||||
|     $i = null; |  | ||||||
|     $a = new ValueAccess($i, ["allow_null" => true]); |  | ||||||
|     self::assertTrue($a->exists()); |  | ||||||
|     self::assertTrue($a->available()); |  | ||||||
|     self::assertSame(null, $a->get($default)); |  | ||||||
| 
 |  | ||||||
|     #
 |  | ||||||
|     $i = false; |  | ||||||
|     $a = new ValueAccess($i, ["allow_false" => false]); |  | ||||||
|     self::assertTrue($a->exists()); |  | ||||||
|     self::assertFalse($a->available()); |  | ||||||
|     self::assertSame($default, $a->get($default)); |  | ||||||
| 
 |  | ||||||
|     $i = false; |  | ||||||
|     $a = new ValueAccess($i, ["allow_false" => true]); |  | ||||||
|     self::assertTrue($a->exists()); |  | ||||||
|     self::assertTrue($a->available()); |  | ||||||
|     self::assertSame(false, $a->get($default)); |  | ||||||
| 
 |  | ||||||
|     #
 |  | ||||||
|     $i = ""; |  | ||||||
|     $a = new ValueAccess($i, ["allow_empty" => false]); |  | ||||||
|     self::assertTrue($a->exists()); |  | ||||||
|     self::assertFalse($a->available()); |  | ||||||
|     self::assertSame($default, $a->get($default)); |  | ||||||
| 
 |  | ||||||
|     $i = ""; |  | ||||||
|     $a = new ValueAccess($i, ["allow_empty" => true]); |  | ||||||
|     self::assertTrue($a->exists()); |  | ||||||
|     self::assertTrue($a->available()); |  | ||||||
|     self::assertSame("", $a->get($default)); |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| @ -1,40 +0,0 @@ | |||||||
| <?php |  | ||||||
| namespace nulib\php\content; |  | ||||||
| 
 |  | ||||||
| use nulib\php\content\impl\html; |  | ||||||
| use nulib\wip\web\content\v; |  | ||||||
| use PHPUnit\Framework\TestCase; |  | ||||||
| 
 |  | ||||||
| class cTest extends TestCase { |  | ||||||
|   function testTo_string() { |  | ||||||
|     self::assertSame("", c::to_string(null)); |  | ||||||
|     self::assertSame("", c::to_string(false)); |  | ||||||
|     self::assertSame("pouet<q/>", c::to_string("pouet<q/>")); |  | ||||||
|     self::assertSame("pouet<q/>", c::to_string(["pouet<q/>"])); |  | ||||||
|     self::assertSame("hello world", c::to_string(["hello", "world"])); |  | ||||||
|     self::assertSame("hello1 world", c::to_string(["hello1", "world"])); |  | ||||||
|     self::assertSame("hello<world>", c::to_string(["hello", "<world>"])); |  | ||||||
|     self::assertSame("<hello>world", c::to_string(["<hello>", "world"])); |  | ||||||
|     self::assertSame("hello,world", c::to_string(["hello,", "world"])); |  | ||||||
|     self::assertSame("hello world", c::to_string(["hello ", "world"])); |  | ||||||
|     self::assertSame("hello. world", c::to_string(["hello.", "world"])); |  | ||||||
|     self::assertSame("hello.<world>", c::to_string(["hello.", "<world>"])); |  | ||||||
| 
 |  | ||||||
|     self::assertSame( |  | ||||||
|       "<h1>title<q/></h1><p>hello<nq/><span>brave<q/></span><span>world<nq/></span></p>", |  | ||||||
|       c::to_string([ |  | ||||||
|         [html::H1, "title<q/>"], |  | ||||||
|         [html::P, [ |  | ||||||
|           "hello<nq/>", |  | ||||||
|           [html::SPAN, "brave<q/>"], |  | ||||||
|           [html::SPAN, ["world<nq/>"]], |  | ||||||
|         ]], |  | ||||||
|       ])); |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
|   function testXxx() { |  | ||||||
|     $content = [[v::h1, "hello"]]; |  | ||||||
|     self::assertSame("<h1>hello</h1>", c::to_string($content)); |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| @ -1,10 +0,0 @@ | |||||||
| <?php |  | ||||||
| namespace nulib\php\content\impl; |  | ||||||
| 
 |  | ||||||
| use nulib\php\content\IContent; |  | ||||||
| 
 |  | ||||||
| class AContent implements IContent { |  | ||||||
|   function getContent(): iterable { |  | ||||||
|     return ["<span>content</span>"]; |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| @ -1,10 +0,0 @@ | |||||||
| <?php |  | ||||||
| namespace nulib\php\content\impl; |  | ||||||
| 
 |  | ||||||
| use nulib\php\content\IPrintable; |  | ||||||
| 
 |  | ||||||
| class APrintable implements IPrintable { |  | ||||||
|   function print(): void { |  | ||||||
|     echo "<p>printable</p>"; |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| @ -1,23 +0,0 @@ | |||||||
| <?php |  | ||||||
| namespace nulib\php\content\impl; |  | ||||||
| 
 |  | ||||||
| use nulib\php\content\c; |  | ||||||
| use nulib\php\content\IContent; |  | ||||||
| 
 |  | ||||||
| class ATag implements IContent { |  | ||||||
|   function __construct(string $tag, $content=null) { |  | ||||||
|     $this->tag = $tag; |  | ||||||
|     $this->content = $content; |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
|   protected $tag; |  | ||||||
|   protected $content; |  | ||||||
| 
 |  | ||||||
|   function getContent(): iterable { |  | ||||||
|     return [ |  | ||||||
|       "<$this->tag>", |  | ||||||
|       ...c::q($this->content), |  | ||||||
|       "</$this->tag>", |  | ||||||
|     ]; |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| @ -1,14 +0,0 @@ | |||||||
| <?php |  | ||||||
| namespace nulib\php\content\impl; |  | ||||||
| 
 |  | ||||||
| class html { |  | ||||||
|   const H1 = [self::class, "h1"]; |  | ||||||
|   const DIV = [self::class, "div"]; |  | ||||||
|   const P = [self::class, "p"]; |  | ||||||
|   const SPAN = [self::class, "span"]; |  | ||||||
| 
 |  | ||||||
|   static function h1($content) { return new ATag("h1", $content); } |  | ||||||
|   static function div($content) { return new ATag("div", $content); } |  | ||||||
|   static function p($content) { return new ATag("p", $content); } |  | ||||||
|   static function span($content) { return new ATag("span", $content); } |  | ||||||
| } |  | ||||||
| @ -1,64 +0,0 @@ | |||||||
| <?php |  | ||||||
| namespace nulib\schema\_scalar; |  | ||||||
| 
 |  | ||||||
| use nulib\tests\TestCase; |  | ||||||
| use nulib\wip\schema\_scalar\ScalarSchema; |  | ||||||
| use nulib\wip\schema\SchemaException; |  | ||||||
| 
 |  | ||||||
| class ScalarSchemaTest extends TestCase { |  | ||||||
|   const NULL_SCHEMA = [ |  | ||||||
|     "type" => [null], |  | ||||||
|     "default" => null, |  | ||||||
|     "title" => null, |  | ||||||
|     "required" => false, |  | ||||||
|     "nullable" => true, |  | ||||||
|     "desc" => null, |  | ||||||
|     "analyzer_func" => null, |  | ||||||
|     "extractor_func" => null, |  | ||||||
|     "parser_func" => null, |  | ||||||
|     "normalizer_func" => null, |  | ||||||
|     "messages" => null, |  | ||||||
|     "formatter_func" => null, |  | ||||||
|     "format" => null, |  | ||||||
|     "" => ["scalar"], |  | ||||||
|     "name" => null, |  | ||||||
|     "pkey" => null, |  | ||||||
|     "header" => null, |  | ||||||
|     "composite" => null, |  | ||||||
|   ]; |  | ||||||
| 
 |  | ||||||
|   static function schema(array $schema): array { |  | ||||||
|     return array_merge(self::NULL_SCHEMA, $schema); |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
|   function testNormalize() { |  | ||||||
|     self::assertSame(self::NULL_SCHEMA, ScalarSchema::normalize(null)); |  | ||||||
|     self::assertSame(self::NULL_SCHEMA, ScalarSchema::normalize([])); |  | ||||||
|     self::assertSame(self::NULL_SCHEMA, ScalarSchema::normalize([null])); |  | ||||||
|     self::assertException(SchemaException::class, function () { |  | ||||||
|       ScalarSchema::normalize([[]]); |  | ||||||
|     }); |  | ||||||
|     self::assertException(SchemaException::class, function () { |  | ||||||
|       ScalarSchema::normalize([[null]]); |  | ||||||
|     }); |  | ||||||
| 
 |  | ||||||
|     $string = self::schema(["type" => ["string"], "nullable" => false]); |  | ||||||
|     self::assertSame($string, ScalarSchema::normalize("string")); |  | ||||||
|     self::assertSame($string, ScalarSchema::normalize(["string"])); |  | ||||||
| 
 |  | ||||||
|     $nstring = self::schema(["type" => ["string"]]); |  | ||||||
|     self::assertSame($nstring, ScalarSchema::normalize(["?string"])); |  | ||||||
|     self::assertSame($nstring, ScalarSchema::normalize(["?string|null"])); |  | ||||||
|     self::assertSame($nstring, ScalarSchema::normalize(["string|null"])); |  | ||||||
|     self::assertSame($nstring, ScalarSchema::normalize([["?string", "null"]])); |  | ||||||
|     self::assertSame($nstring, ScalarSchema::normalize([["string", "null"]])); |  | ||||||
|     self::assertSame($nstring, ScalarSchema::normalize([["string", null]])); |  | ||||||
| 
 |  | ||||||
|     $key = self::schema(["type" => ["string", "int"], "nullable" => false]); |  | ||||||
|     self::assertSame($key, ScalarSchema::normalize("string|int")); |  | ||||||
| 
 |  | ||||||
|     $nkey = self::schema(["type" => ["string", "int"], "nullable" => true]); |  | ||||||
|     self::assertSame($nkey, ScalarSchema::normalize("?string|int")); |  | ||||||
|     self::assertSame($nkey, ScalarSchema::normalize("string|?int")); |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| @ -1,111 +0,0 @@ | |||||||
| <?php |  | ||||||
| namespace nulib\schema\types; |  | ||||||
| 
 |  | ||||||
| use Exception; |  | ||||||
| use nulib\tests\TestCase; |  | ||||||
| use nulib\schema\_scalar\ScalarValue; |  | ||||||
| use nulib\schema\Schema; |  | ||||||
| 
 |  | ||||||
| class boolTest extends TestCase { |  | ||||||
|   function commonTests($destv, &$dest, callable $destvSetter): void { |  | ||||||
|     $destv->set(true); |  | ||||||
|     self::assertSame(true, $destv->get()); |  | ||||||
|     self::assertSame(true, $dest); |  | ||||||
|     self::assertSame("Oui", $destv->format()); |  | ||||||
|     self::assertSame("Oui", $destv->format("OuiNonNull")); |  | ||||||
|     self::assertSame("O", $destv->format("ON")); |  | ||||||
|     self::assertSame("O", $destv->format("ONN")); |  | ||||||
| 
 |  | ||||||
|     $destv->set(false); |  | ||||||
|     self::assertSame(false, $destv->get()); |  | ||||||
|     self::assertSame(false, $dest); |  | ||||||
|     self::assertSame("Non", $destv->format()); |  | ||||||
|     self::assertSame("Non", $destv->format("OuiNonNull")); |  | ||||||
|     self::assertSame("N", $destv->format("ON")); |  | ||||||
|     self::assertSame("N", $destv->format("ONN")); |  | ||||||
| 
 |  | ||||||
|     $destv->set("yes"); |  | ||||||
|     self::assertSame(true, $destv->get()); |  | ||||||
| 
 |  | ||||||
|     $destv->set(" yes "); |  | ||||||
|     self::assertSame(true, $destv->get()); |  | ||||||
| 
 |  | ||||||
|     $destv->set("12"); |  | ||||||
|     self::assertSame(true, $destv->get()); |  | ||||||
| 
 |  | ||||||
|     $destv->set(12); |  | ||||||
|     self::assertSame(true, $destv->get()); |  | ||||||
| 
 |  | ||||||
|     $destv->set("no"); |  | ||||||
|     self::assertSame(false, $destv->get()); |  | ||||||
| 
 |  | ||||||
|     $destv->set(" no "); |  | ||||||
|     self::assertSame(false, $destv->get()); |  | ||||||
| 
 |  | ||||||
|     $destv->set("0"); |  | ||||||
|     self::assertSame(false, $destv->get()); |  | ||||||
| 
 |  | ||||||
|     $destv->set(0); |  | ||||||
|     self::assertSame(false, $destv->get()); |  | ||||||
| 
 |  | ||||||
|     $destv->set(12.34); |  | ||||||
|     self::assertSame(true, $destv->get()); |  | ||||||
| 
 |  | ||||||
|     self::assertException(Exception::class, $destvSetter("a")); |  | ||||||
|     self::assertException(Exception::class, $destvSetter([])); |  | ||||||
|     self::assertException(Exception::class, $destvSetter(["a"])); |  | ||||||
| 
 |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
|   function testBool() { |  | ||||||
|     /** @var ScalarValue $destv */ |  | ||||||
|     Schema::nv($destv, $dest, null, $schema, "bool"); |  | ||||||
|     $destvSetter = function($value) use($destv) { |  | ||||||
|       return function() use($destv, $value) { |  | ||||||
|         $destv->set($value); |  | ||||||
|       }; |  | ||||||
|     }; |  | ||||||
| 
 |  | ||||||
|     self::assertException(Exception::class, $destvSetter(null)); |  | ||||||
|     self::assertException(Exception::class, $destvSetter("")); |  | ||||||
|     self::assertException(Exception::class, $destvSetter(" ")); |  | ||||||
| 
 |  | ||||||
|     $this->commonTests($destv, $dest, $destvSetter); |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
|   function testNbool() { |  | ||||||
|     /** @var ScalarValue $destv */ |  | ||||||
|     Schema::nv($destv, $dest, null, $schema, "?bool"); |  | ||||||
|     $destvSetter = function($value) use($destv) { |  | ||||||
|       return function() use($destv, $value) { |  | ||||||
|         $destv->set($value); |  | ||||||
|       }; |  | ||||||
|     }; |  | ||||||
| 
 |  | ||||||
|     $destv->set(null); |  | ||||||
|     self::assertNull($destv->get()); |  | ||||||
|     self::assertNull($dest); |  | ||||||
|     self::assertSame("Non", $destv->format()); |  | ||||||
|     self::assertSame("", $destv->format("OuiNonNull")); |  | ||||||
|     self::assertSame("N", $destv->format("ON")); |  | ||||||
|     self::assertSame("", $destv->format("ONN")); |  | ||||||
| 
 |  | ||||||
|     $destv->set(""); |  | ||||||
|     self::assertNull($destv->get()); |  | ||||||
|     self::assertNull($dest); |  | ||||||
|     self::assertSame("Non", $destv->format()); |  | ||||||
|     self::assertSame("", $destv->format("OuiNonNull")); |  | ||||||
|     self::assertSame("N", $destv->format("ON")); |  | ||||||
|     self::assertSame("", $destv->format("ONN")); |  | ||||||
| 
 |  | ||||||
|     $destv->set(" "); |  | ||||||
|     self::assertNull($destv->get()); |  | ||||||
|     self::assertNull($dest); |  | ||||||
|     self::assertSame("Non", $destv->format()); |  | ||||||
|     self::assertSame("", $destv->format("OuiNonNull")); |  | ||||||
|     self::assertSame("N", $destv->format("ON")); |  | ||||||
|     self::assertSame("", $destv->format("ONN")); |  | ||||||
| 
 |  | ||||||
|     $this->commonTests($destv, $dest, $destvSetter); |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| @ -1,139 +0,0 @@ | |||||||
| <?php |  | ||||||
| namespace nulib\schema\types; |  | ||||||
| 
 |  | ||||||
| use Exception; |  | ||||||
| use nulib\tests\TestCase; |  | ||||||
| use nulib\schema\_scalar\ScalarValue; |  | ||||||
| use nulib\schema\Schema; |  | ||||||
| 
 |  | ||||||
| class floatTest extends TestCase { |  | ||||||
|   function commonTests($destv, &$dest, callable $destvSetter): void { |  | ||||||
|     $destv->set(12); |  | ||||||
|     self::assertSame(12.0, $destv->get()); |  | ||||||
|     self::assertSame(12.0, $dest); |  | ||||||
|     self::assertSame("12", $destv->format()); |  | ||||||
|     self::assertSame("0012", $destv->format("%04u")); |  | ||||||
| 
 |  | ||||||
|     $destv->set("12"); |  | ||||||
|     self::assertSame(12.0, $destv->get()); |  | ||||||
| 
 |  | ||||||
|     $destv->set(" 12 "); |  | ||||||
|     self::assertSame(12.0, $destv->get()); |  | ||||||
| 
 |  | ||||||
|     $destv->set(12.34); |  | ||||||
|     self::assertSame(12.34, $destv->get()); |  | ||||||
| 
 |  | ||||||
|     $destv->set(true); |  | ||||||
|     self::assertSame(1.0, $destv->get()); |  | ||||||
| 
 |  | ||||||
|     self::assertException(Exception::class, $destvSetter("a")); |  | ||||||
|     self::assertException(Exception::class, $destvSetter([])); |  | ||||||
|     self::assertException(Exception::class, $destvSetter(["a"])); |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
|   function testFloat() { |  | ||||||
|     /** @var ScalarValue $destv */ |  | ||||||
|     Schema::nv($destv, $dest, null, $schema, "float"); |  | ||||||
|     $destvSetter = function($value) use($destv) { |  | ||||||
|       return function() use($destv, $value) { |  | ||||||
|         $destv->set($value); |  | ||||||
|       }; |  | ||||||
|     }; |  | ||||||
| 
 |  | ||||||
|     self::assertException(Exception::class, $destvSetter(null)); |  | ||||||
|     self::assertException(Exception::class, $destvSetter("")); |  | ||||||
|     self::assertException(Exception::class, $destvSetter(" ")); |  | ||||||
| 
 |  | ||||||
|     // valeur non requise donc retourne null
 |  | ||||||
|     $destv->set(false); |  | ||||||
|     self::assertNull($destv->get()); |  | ||||||
| 
 |  | ||||||
|     $this->commonTests($destv, $dest, $destvSetter); |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
|   function testRequiredFloat() { |  | ||||||
|     /** @var ScalarValue $destv */ |  | ||||||
|     Schema::nv($destv, $dest, null, $schema, [ |  | ||||||
|       "float", null, |  | ||||||
|       "required" => true, |  | ||||||
|     ]); |  | ||||||
|     $destvSetter = function($value) use($destv) { |  | ||||||
|       return function() use($destv, $value) { |  | ||||||
|         $destv->set($value); |  | ||||||
|       }; |  | ||||||
|     }; |  | ||||||
| 
 |  | ||||||
|     self::assertException(Exception::class, $destvSetter(null)); |  | ||||||
|     self::assertException(Exception::class, $destvSetter("")); |  | ||||||
|     self::assertException(Exception::class, $destvSetter(" ")); |  | ||||||
| 
 |  | ||||||
|     // valeur requise donc lance une exception
 |  | ||||||
|     self::assertException(Exception::class, $destvSetter(false)); |  | ||||||
| 
 |  | ||||||
|     $this->commonTests($destv, $dest, $destvSetter); |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
|   function testNfloat() { |  | ||||||
|     /** @var ScalarValue $destv */ |  | ||||||
|     Schema::nv($destv, $dest, null, $schema, "?float"); |  | ||||||
|     $destvSetter = function($value) use($destv) { |  | ||||||
|       return function() use($destv, $value) { |  | ||||||
|         $destv->set($value); |  | ||||||
|       }; |  | ||||||
|     }; |  | ||||||
| 
 |  | ||||||
|     $destv->set(null); |  | ||||||
|     self::assertNull($destv->get()); |  | ||||||
|     self::assertNull($dest); |  | ||||||
|     self::assertSame("", $destv->format()); |  | ||||||
| 
 |  | ||||||
|     $destv->set(""); |  | ||||||
|     self::assertNull($destv->get()); |  | ||||||
|     self::assertNull($dest); |  | ||||||
|     self::assertSame("", $destv->format()); |  | ||||||
| 
 |  | ||||||
|     $destv->set(" "); |  | ||||||
|     self::assertNull($destv->get()); |  | ||||||
|     self::assertNull($dest); |  | ||||||
|     self::assertSame("", $destv->format()); |  | ||||||
| 
 |  | ||||||
|     // valeur non requise donc retourne null
 |  | ||||||
|     $destv->set(false); |  | ||||||
|     self::assertNull($destv->get()); |  | ||||||
| 
 |  | ||||||
|     $this->commonTests($destv, $dest, $destvSetter); |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
|   function testRequiredNfloat() { |  | ||||||
|     /** @var ScalarValue $destv */ |  | ||||||
|     Schema::nv($destv, $dest, null, $schema, [ |  | ||||||
|       "?float", null, |  | ||||||
|       "required" => true, |  | ||||||
|     ]); |  | ||||||
|     $destvSetter = function($value) use($destv) { |  | ||||||
|       return function() use($destv, $value) { |  | ||||||
|         $destv->set($value); |  | ||||||
|       }; |  | ||||||
|     }; |  | ||||||
| 
 |  | ||||||
|     $destv->set(null); |  | ||||||
|     self::assertNull($destv->get()); |  | ||||||
|     self::assertNull($dest); |  | ||||||
|     self::assertSame("", $destv->format()); |  | ||||||
| 
 |  | ||||||
|     $destv->set(""); |  | ||||||
|     self::assertNull($destv->get()); |  | ||||||
|     self::assertNull($dest); |  | ||||||
|     self::assertSame("", $destv->format()); |  | ||||||
| 
 |  | ||||||
|     $destv->set(" "); |  | ||||||
|     self::assertNull($destv->get()); |  | ||||||
|     self::assertNull($dest); |  | ||||||
|     self::assertSame("", $destv->format()); |  | ||||||
| 
 |  | ||||||
|     // valeur requise donc lance une exception
 |  | ||||||
|     self::assertException(Exception::class, $destvSetter(false)); |  | ||||||
| 
 |  | ||||||
|     $this->commonTests($destv, $dest, $destvSetter); |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| @ -1,139 +0,0 @@ | |||||||
| <?php |  | ||||||
| namespace nulib\schema\types; |  | ||||||
| 
 |  | ||||||
| use Exception; |  | ||||||
| use nulib\tests\TestCase; |  | ||||||
| use nulib\schema\_scalar\ScalarValue; |  | ||||||
| use nulib\schema\Schema; |  | ||||||
| 
 |  | ||||||
| class intTest extends TestCase { |  | ||||||
|   function commonTests($destv, &$dest, callable $destvSetter): void { |  | ||||||
|     $destv->set(12); |  | ||||||
|     self::assertSame(12, $destv->get()); |  | ||||||
|     self::assertSame(12, $dest); |  | ||||||
|     self::assertSame("12", $destv->format()); |  | ||||||
|     self::assertSame("0012", $destv->format("%04u")); |  | ||||||
| 
 |  | ||||||
|     $destv->set("12"); |  | ||||||
|     self::assertSame(12, $destv->get()); |  | ||||||
| 
 |  | ||||||
|     $destv->set(" 12 "); |  | ||||||
|     self::assertSame(12, $destv->get()); |  | ||||||
| 
 |  | ||||||
|     $destv->set(12.34); |  | ||||||
|     self::assertSame(12, $destv->get()); |  | ||||||
| 
 |  | ||||||
|     $destv->set(true); |  | ||||||
|     self::assertSame(1, $destv->get()); |  | ||||||
| 
 |  | ||||||
|     self::assertException(Exception::class, $destvSetter("a")); |  | ||||||
|     self::assertException(Exception::class, $destvSetter([])); |  | ||||||
|     self::assertException(Exception::class, $destvSetter(["a"])); |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
|   function testInt() { |  | ||||||
|     /** @var ScalarValue $destv */ |  | ||||||
|     Schema::nv($destv, $dest, null, $schema, "int"); |  | ||||||
|     $destvSetter = function($value) use($destv) { |  | ||||||
|       return function() use($destv, $value) { |  | ||||||
|         $destv->set($value); |  | ||||||
|       }; |  | ||||||
|     }; |  | ||||||
| 
 |  | ||||||
|     self::assertException(Exception::class, $destvSetter(null)); |  | ||||||
|     self::assertException(Exception::class, $destvSetter("")); |  | ||||||
|     self::assertException(Exception::class, $destvSetter(" ")); |  | ||||||
| 
 |  | ||||||
|     // valeur non requise donc retourne null
 |  | ||||||
|     $destv->set(false); |  | ||||||
|     self::assertNull($destv->get()); |  | ||||||
| 
 |  | ||||||
|     $this->commonTests($destv, $dest, $destvSetter); |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
|   function testRequiredInt() { |  | ||||||
|     /** @var ScalarValue $destv */ |  | ||||||
|     Schema::nv($destv, $dest, null, $schema, [ |  | ||||||
|       "int", null, |  | ||||||
|       "required" => true, |  | ||||||
|     ]); |  | ||||||
|     $destvSetter = function($value) use($destv) { |  | ||||||
|       return function() use($destv, $value) { |  | ||||||
|         $destv->set($value); |  | ||||||
|       }; |  | ||||||
|     }; |  | ||||||
| 
 |  | ||||||
|     self::assertException(Exception::class, $destvSetter(null)); |  | ||||||
|     self::assertException(Exception::class, $destvSetter("")); |  | ||||||
|     self::assertException(Exception::class, $destvSetter(" ")); |  | ||||||
| 
 |  | ||||||
|     // valeur requise donc lance une exception
 |  | ||||||
|     self::assertException(Exception::class, $destvSetter(false)); |  | ||||||
| 
 |  | ||||||
|     $this->commonTests($destv, $dest, $destvSetter); |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
|   function testNint() { |  | ||||||
|     /** @var ScalarValue $destv */ |  | ||||||
|     Schema::nv($destv, $dest, null, $schema, "?int"); |  | ||||||
|     $destvSetter = function($value) use($destv) { |  | ||||||
|       return function() use($destv, $value) { |  | ||||||
|         $destv->set($value); |  | ||||||
|       }; |  | ||||||
|     }; |  | ||||||
| 
 |  | ||||||
|     $destv->set(null); |  | ||||||
|     self::assertNull($destv->get()); |  | ||||||
|     self::assertNull($dest); |  | ||||||
|     self::assertSame("", $destv->format()); |  | ||||||
| 
 |  | ||||||
|     $destv->set(""); |  | ||||||
|     self::assertNull($destv->get()); |  | ||||||
|     self::assertNull($dest); |  | ||||||
|     self::assertSame("", $destv->format()); |  | ||||||
| 
 |  | ||||||
|     $destv->set(" "); |  | ||||||
|     self::assertNull($destv->get()); |  | ||||||
|     self::assertNull($dest); |  | ||||||
|     self::assertSame("", $destv->format()); |  | ||||||
| 
 |  | ||||||
|     // valeur non requise donc retourne null
 |  | ||||||
|     $destv->set(false); |  | ||||||
|     self::assertNull($destv->get()); |  | ||||||
| 
 |  | ||||||
|     $this->commonTests($destv, $dest, $destvSetter); |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
|   function testRequiredNint() { |  | ||||||
|     /** @var ScalarValue $destv */ |  | ||||||
|     Schema::nv($destv, $dest, null, $schema, [ |  | ||||||
|       "?int", null, |  | ||||||
|       "required" => true, |  | ||||||
|     ]); |  | ||||||
|     $destvSetter = function($value) use($destv) { |  | ||||||
|       return function() use($destv, $value) { |  | ||||||
|         $destv->set($value); |  | ||||||
|       }; |  | ||||||
|     }; |  | ||||||
| 
 |  | ||||||
|     $destv->set(null); |  | ||||||
|     self::assertNull($destv->get()); |  | ||||||
|     self::assertNull($dest); |  | ||||||
|     self::assertSame("", $destv->format()); |  | ||||||
| 
 |  | ||||||
|     $destv->set(""); |  | ||||||
|     self::assertNull($destv->get()); |  | ||||||
|     self::assertNull($dest); |  | ||||||
|     self::assertSame("", $destv->format()); |  | ||||||
| 
 |  | ||||||
|     $destv->set(" "); |  | ||||||
|     self::assertNull($destv->get()); |  | ||||||
|     self::assertNull($dest); |  | ||||||
|     self::assertSame("", $destv->format()); |  | ||||||
| 
 |  | ||||||
|     // valeur requise donc lance une exception
 |  | ||||||
|     self::assertException(Exception::class, $destvSetter(false)); |  | ||||||
| 
 |  | ||||||
|     $this->commonTests($destv, $dest, $destvSetter); |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| @ -1,123 +0,0 @@ | |||||||
| <?php |  | ||||||
| namespace nulib\schema\types; |  | ||||||
| 
 |  | ||||||
| use Exception; |  | ||||||
| use nulib\tests\TestCase; |  | ||||||
| use nulib\wip\schema\_scalar\ScalarValue; |  | ||||||
| use nulib\wip\schema\Schema; |  | ||||||
| 
 |  | ||||||
| class strTest extends TestCase { |  | ||||||
|   function commonTests($destv, &$dest, callable $destvSetter): void { |  | ||||||
|     $destv->set(""); |  | ||||||
|     self::assertSame("", $destv->get()); |  | ||||||
|     self::assertSame("", $dest); |  | ||||||
| 
 |  | ||||||
|     $destv->set(" "); |  | ||||||
|     self::assertSame(" ", $destv->get()); |  | ||||||
|     self::assertSame(" ", $dest); |  | ||||||
| 
 |  | ||||||
|     $destv->set("a"); |  | ||||||
|     self::assertSame("a", $destv->get()); |  | ||||||
|     self::assertSame("a", $dest); |  | ||||||
| 
 |  | ||||||
|     $destv->set("12"); |  | ||||||
|     self::assertSame("12", $destv->get()); |  | ||||||
| 
 |  | ||||||
|     $destv->set(" 12 "); |  | ||||||
|     self::assertSame(" 12 ", $destv->get()); |  | ||||||
| 
 |  | ||||||
|     $destv->set(12); |  | ||||||
|     self::assertSame("12", $destv->get()); |  | ||||||
| 
 |  | ||||||
|     $destv->set(12.34); |  | ||||||
|     self::assertSame("12.34", $destv->get()); |  | ||||||
| 
 |  | ||||||
|     $destv->set(true); |  | ||||||
|     self::assertSame("1", $destv->get()); |  | ||||||
| 
 |  | ||||||
|     self::assertException(Exception::class, $destvSetter([])); |  | ||||||
|     self::assertException(Exception::class, $destvSetter(["a"])); |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
|   function testStr() { |  | ||||||
|     /** @var ScalarValue $destv */ |  | ||||||
|     Schema::nv($destv, $dest, null, $schema, "string"); |  | ||||||
|     $destvSetter = function($value) use($destv) { |  | ||||||
|       return function() use($destv, $value) { |  | ||||||
|         $destv->set($value); |  | ||||||
|       }; |  | ||||||
|     }; |  | ||||||
| 
 |  | ||||||
|     self::assertException(Exception::class, $destvSetter(null)); |  | ||||||
| 
 |  | ||||||
|     // valeur non requise donc retourne null
 |  | ||||||
|     $destv->set(false); |  | ||||||
|     self::assertNull($destv->get()); |  | ||||||
| 
 |  | ||||||
|     $this->commonTests($destv, $dest, $destvSetter); |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
|   function testRequiredStr() { |  | ||||||
|     /** @var ScalarValue $destv */ |  | ||||||
|     Schema::nv($destv, $dest, null, $schema, [ |  | ||||||
|       "string", null, |  | ||||||
|       "required" => true, |  | ||||||
|     ]); |  | ||||||
|     $destvSetter = function($value) use($destv) { |  | ||||||
|       return function() use($destv, $value) { |  | ||||||
|         $destv->set($value); |  | ||||||
|       }; |  | ||||||
|     }; |  | ||||||
| 
 |  | ||||||
|     self::assertException(Exception::class, $destvSetter(null)); |  | ||||||
| 
 |  | ||||||
|     // valeur requise donc lance une exception
 |  | ||||||
|     self::assertException(Exception::class, $destvSetter(false)); |  | ||||||
| 
 |  | ||||||
|     $this->commonTests($destv, $dest, $destvSetter); |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
|   function testNstr() { |  | ||||||
|     /** @var ScalarValue $destv */ |  | ||||||
|     Schema::nv($destv, $dest, null, $schema, "?string"); |  | ||||||
|     $destvSetter = function($value) use($destv) { |  | ||||||
|       return function() use($destv, $value) { |  | ||||||
|         $destv->set($value); |  | ||||||
|       }; |  | ||||||
|     }; |  | ||||||
| 
 |  | ||||||
|     $destv->set(null); |  | ||||||
|     self::assertNull($destv->get()); |  | ||||||
|     self::assertNull($dest); |  | ||||||
|     self::assertSame("", $destv->format()); |  | ||||||
| 
 |  | ||||||
|     // valeur non requise donc retourne null
 |  | ||||||
|     $destv->set(false); |  | ||||||
|     self::assertNull($destv->get()); |  | ||||||
| 
 |  | ||||||
|     $this->commonTests($destv, $dest, $destvSetter); |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
|   function testRequiredNstr() { |  | ||||||
|     /** @var ScalarValue $destv */ |  | ||||||
|     Schema::nv($destv, $dest, null, $schema, [ |  | ||||||
|       "?string", null, |  | ||||||
|       "required" => true, |  | ||||||
|     ]); |  | ||||||
|     $destvSetter = function($value) use($destv) { |  | ||||||
|       return function() use($destv, $value) { |  | ||||||
|         $destv->set($value); |  | ||||||
|       }; |  | ||||||
|     }; |  | ||||||
| 
 |  | ||||||
|     $destv->set(null); |  | ||||||
|     self::assertNull($destv->get()); |  | ||||||
|     self::assertNull($dest); |  | ||||||
|     self::assertSame("", $destv->format()); |  | ||||||
| 
 |  | ||||||
|     // valeur requise donc lance une exception
 |  | ||||||
|     self::assertException(Exception::class, $destvSetter(false)); |  | ||||||
| 
 |  | ||||||
|     $this->commonTests($destv, $dest, $destvSetter); |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| @ -1,29 +0,0 @@ | |||||||
| <?php |  | ||||||
| namespace nulib\schema\types; |  | ||||||
| 
 |  | ||||||
| use nulib\tests\TestCase; |  | ||||||
| use nulib\schema\_scalar\ScalarValue; |  | ||||||
| use nulib\schema\Schema; |  | ||||||
| 
 |  | ||||||
| class unionTest extends TestCase { |  | ||||||
|   function testUnionTypes() { |  | ||||||
|     ## l'ordre des types doit être respecté
 |  | ||||||
|      |  | ||||||
|     # string puis int
 |  | ||||||
|     /** @var ScalarValue $siv */ |  | ||||||
|     Schema::nv($siv, $si, null, $sis, "string|int"); |  | ||||||
| 
 |  | ||||||
|     $siv->set("12"); |  | ||||||
|     self::assertSame("12", $si); |  | ||||||
|     $siv->set(12); |  | ||||||
|     self::assertSame(12, $si); |  | ||||||
| 
 |  | ||||||
|     # int puis string
 |  | ||||||
|     Schema::nv($isv, $is, null, $iss, "int|string"); |  | ||||||
| 
 |  | ||||||
|     $isv->set("12"); |  | ||||||
|     self::assertSame("12", $is); |  | ||||||
|     $isv->set(12); |  | ||||||
|     self::assertSame(12, $is); |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| @ -455,15 +455,18 @@ OPTIONS | |||||||
| 
 | 
 | ||||||
| function host_docker_run() { | function host_docker_run() { | ||||||
|     # lancer une commande avec docker |     # lancer une commande avec docker | ||||||
|     SOPTS=+w: |     if [ "$1" == composer ]; then | ||||||
|     LOPTS=help,chdir:,no-use-rslave |         : # pas d'analyse d'argument pour composer | ||||||
|     args="$(getopt -n "$MYNAME" -o "$SOPTS" -l "$LOPTS" -- "$@")" || exit 1; eval "set -- $args" |     else | ||||||
|  |         SOPTS=+w: | ||||||
|  |         LOPTS=help,chdir:,no-use-rslave | ||||||
|  |         args="$(getopt -n "$MYNAME" -o "$SOPTS" -l "$LOPTS" -- "$@")" || exit 1; eval "set -- $args" | ||||||
| 
 | 
 | ||||||
|     while [ $# -gt 0 ]; do |         while [ $# -gt 0 ]; do | ||||||
|         case "$1" in |             case "$1" in | ||||||
|         --) shift; break;; |             --) shift; break;; | ||||||
|         --help) |             --help) | ||||||
|             eecho "\ |                 eecho "\ | ||||||
| runphp: lancer une commande dans un environnement PHP déterminé | runphp: lancer une commande dans un environnement PHP déterminé | ||||||
| 
 | 
 | ||||||
| USAGE | USAGE | ||||||
| @ -490,14 +493,15 @@ OPTIONS | |||||||
|         aller dans le répertoire spécifié avant de lancer la commande |         aller dans le répertoire spécifié avant de lancer la commande | ||||||
|     --no-use-rslave |     --no-use-rslave | ||||||
|         paramètre montage des volumes" |         paramètre montage des volumes" | ||||||
|             exit 0 |                 exit 0 | ||||||
|             ;; |                 ;; | ||||||
|         -w|--chdir) shift; Chdir="$1";; |             -w|--chdir) shift; Chdir="$1";; | ||||||
|         --no-use-rslave) UseRslave=;; |             --no-use-rslave) UseRslave=;; | ||||||
|         *) die "$1: option non configurée";; |             *) die "$1: option non configurée";; | ||||||
|         esac |             esac | ||||||
|         shift |             shift | ||||||
|     done |         done | ||||||
|  |     fi | ||||||
| 
 | 
 | ||||||
|     args=( |     args=( | ||||||
|         run -it --rm |         run -it --rm | ||||||
| @ -573,20 +577,24 @@ function container_exec() { | |||||||
|         fi |         fi | ||||||
|     fi |     fi | ||||||
| 
 | 
 | ||||||
|     SOPTS=+w: |     if [ "$1" == composer ]; then | ||||||
|     LOPTS=chdir: |         : # pas d'analyse d'argument pour composer | ||||||
|     args="$(getopt -n "$MYNAME" -o "$SOPTS" -l "$LOPTS" -- "$@")" || exit 1; eval "set -- $args" |     else | ||||||
|  |         SOPTS=+w: | ||||||
|  |         LOPTS=chdir: | ||||||
|  |         args="$(getopt -n "$MYNAME" -o "$SOPTS" -l "$LOPTS" -- "$@")" || exit 1; eval "set -- $args" | ||||||
| 
 | 
 | ||||||
|     chdir= |         chdir= | ||||||
|     action= |         action= | ||||||
|     while [ $# -gt 0 ]; do |         while [ $# -gt 0 ]; do | ||||||
|         case "$1" in |             case "$1" in | ||||||
|         --) shift; break;; |             --) shift; break;; | ||||||
|         -w|--chdir) shift; chdir="$1";; |             -w|--chdir) shift; chdir="$1";; | ||||||
|         *) die "$1: option non configurée";; |             *) die "$1: option non configurée";; | ||||||
|         esac |             esac | ||||||
|         shift |             shift | ||||||
|     done |         done | ||||||
|  |     fi | ||||||
| 
 | 
 | ||||||
|     if [ $# -eq 0 ]; then |     if [ $# -eq 0 ]; then | ||||||
|         die "no command specified" |         die "no command specified" | ||||||
|  | |||||||
										
											Binary file not shown.
										
									
								
							
		Reference in New Issue
	
	Block a user