<pman>Intégration de la branche dev74

This commit is contained in:
Jephté Clain 2025-03-02 19:24:09 +04:00
commit f1f033e0e9
11 changed files with 312 additions and 25 deletions

8
.pman.yml Normal file
View 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

View File

@ -2,20 +2,13 @@
## configuration par défaut
# branche upstream
UPSTREAM=
# branches de développement
DEVELOP=develop
FEATURE=wip/
# branche de préparation de release
RELEASE=release-
# branche de release
MAIN=master
TAG_PREFIX=
TAG_SUFFIX=
# branche de hotfix
HOTFIX=hotfix-
# branche de distribution
DIST=
# désactiver les releases automatiques?
NOAUTO=

View File

@ -5,15 +5,23 @@
# les branches sont mergées dans cet ordre:
# upstream --> develop --> [release -->] main --> dist
# feature _/ hotfix _/
# branche upstream
UPSTREAM=
# branches de développement
DEVELOP=develop
FEATURE=wip/
# branche de préparation de release
RELEASE=release-
# branche de release
MAIN=master
TAG_PREFIX=
TAG_SUFFIX=
# branche de hotfix
HOTFIX=hotfix-
# branche de distribution
DIST=
# désactiver les releases automatiques?
NOAUTO=
CONFIG_VARS=(
@ -210,6 +218,9 @@ function load_branches() {
}
function load_config() {
if [ "${ConfigFile#::}" != "$ConfigFile" ]; then
ConfigFile="$NULIBDIR/bash/src/pman${ConfigFile#::}.conf.sh"
fi
if [ -n "$ConfigFile" ]; then
source "$ConfigFile" || die || return
elif [ -n "$ConfigBranch" ]; then
@ -224,12 +235,16 @@ function load_config() {
elif [ -f .pman.conf ]; then
ConfigFile="$(pwd)/.pman.conf"
source "$ConfigFile"
elif [ -n "${MYNAME#prel}" ]; then
elif [ -n "$1" -a -n "${MYNAME#$1}" ]; then
ConfigFile="$NULIBDIR/bash/src/pman${MYNAME#$1}.conf.sh"
source "$ConfigFile"
else
ConfigFile="$NULIBDIR/bash/src/pman.conf.sh"
fi
# S'assurer que nulib est dans le PATH pour que les scripts utilisateurs
# puissent utiliser les outils fournis
export PATH="$NULIBDIR/bin:$PATH"
}
################################################################################

View 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();
}

View File

@ -134,7 +134,15 @@ SquashMsg=
[ -z "$PMAN_NO_DELETE" ] && Delete=1 || Delete=
args=(
"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:
AFTER_MERGE_<srcType>
AFTER_DELETE_<srcType>
AFTER_PUSH_<destType>
xxxType valant UPSTREAM, DEVELOP, FEATURE, RELEASE, MAIN, HOTFIX, DIST"
-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"

View File

@ -34,16 +34,12 @@ function show_action() {
# Initialisation
################################################################################
function init_repo_action() {
[ ${#LocalBranches[*]} -eq 0 ] || die "Ce dépôt a déjà été initialisé"
local -a push_branches
if [ ! -f .pman.conf ]; then
function _init_config() {
if [ ! -f .pman.conf -o -n "$ForceCreate" ]; then
ac_set_tmpfile config
cp "$ConfigFile" "$config"
"${EDITOR:-nano}" "$config"
[ -s "$config" ] || exit_with ewarn "Initialisation du dépôt annulée"
[ -s "$config" ] || return 1
cp "$config" .pman.conf
if testdiff .pman.conf "$ConfigFile"; then
@ -59,6 +55,15 @@ function init_repo_action() {
.*.swp"
git add .gitignore
fi
return 0
}
function init_repo_action() {
[ ${#LocalBranches[*]} -eq 0 ] || die "Ce dépôt a déjà été initialisé"
local -a push_branches
_init_config || exit_with ewarn "Initialisation du dépôt annulée"
einfo "Création de la branche $MAIN"
git symbolic-ref HEAD "refs/heads/$MAIN"
@ -72,6 +77,18 @@ function init_repo_action() {
_push_branches
}
function init_config_action() {
[ -f .pman.conf ] && die "La configuration pman a déjà été initialisée"
local -a push_branches
_init_config || exit_with ewarn "Initialisation de la configuration annulée"
git commit -m "configuration pman"
push_branches+=("$CurrentBranch")
_push_branches
}
function init_develop_action() {
if [ -z "$DevelopBranch" ]; then
[ -n "$DEVELOP" ] || die "La branche DEVELOP n'a pas été définie"
@ -174,6 +191,7 @@ function init_action() {
local what="${1:-develop}"; shift
case "$what" in
init|repo|r) init_repo_action "$@";;
config) init_config_action "$@";;
main|m) git checkout -q "$MAIN";;
develop|dev|d) init_develop_action "$@";;
upstream|up|u) init_upstream_action "$@";;
@ -192,9 +210,10 @@ ConfigFile=
action=init
Origin=
Push=1
ForceCreate=
args=(
"gérer un projet git"
"repo|develop|upstream|dist
"repo|config|develop|upstream|dist
INITIALISATION
@ -219,6 +238,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"
-w,--show-config action=show "++\
afficher la configuration chargée"
--composer-select-profile action=composer_select_profile "\
sélectionner le profil composer spécifié en argument"
-O:,--origin Origin= "++\
origine vers laquelle pousser les branches"
-n,--no-push Push= "\
@ -226,6 +247,8 @@ ne pas pousser les branches vers leur origine après leur création"
--push Push=1 "++\
pousser les branches vers leur origine après leur création.
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[@]}"
@ -244,6 +267,9 @@ init)
git_ensure_cleancheckout
init_action "$@"
;;
composer_select_profile)
exec "$MYDIR/_pman-$action.php" "$@"
;;
*)
die "$action: action non implémentée"
;;

View File

@ -42,6 +42,9 @@ function create_release_action() {
merge_hotfix_action "$@"; return $?
fi
[ -n "$ManualRelease" ] && ewarn "\
L'option --no-merge a été forcée puisque ce dépôt ne supporte pas les releases automatiques"
if [ -z "$Version" -a -n "$CurrentVersion" -a -f VERSION.txt ]; then
Version="$(<VERSION.txt)"
Tag="$TAG_PREFIX$Version$TAG_SUFFIX"
@ -182,7 +185,15 @@ CurrentVersion=
ForceCreate=
args=(
"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:
AFTER_CREATE_RELEASE
AFTER_MERGE_RELEASE
AFTER_PUSH_RELEASE"
-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"
@ -208,11 +219,11 @@ ne pas pousser les branches vers leur origine après la création de la release"
--push Push=1 "++\
pousser les branches vers leur origine après la création de la release.
c'est l'option par défaut"
-v:,--version Version= "\
-v:,--version:VERSION Version= "\
spécifier la version de la release à créer"
-C,--current-version CurrentVersion=1 "++\
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= "\
forcer la création de la release même si le tag correspond à la version existe déjà"
)
parse_args "$@"; set -- "${args[@]}"
@ -223,10 +234,8 @@ load_branches all
load_config "$MYNAME"
load_branches current "$1"; shift
if [ -n "$Merge" -a -n "$NOAUTO" ]; then
ewarn "L'option --no-merge a été forcée puisque ce dépôt ne supporte pas les releases automatiques"
Merge=
fi
[ -n "$Merge" -a -n "$NOAUTO" ] && ManualRelease=1 || ManualRelease=
[ -n "$ManualRelease" ] && Merge=
[ -z "$Merge" ] && Push=
CantPush=

View File

@ -2,7 +2,6 @@
namespace nulib\ext;
use Exception;
use nulib\ext\json\JsonException;
use nulib\file;
use nulib\os\IOException;

View File

@ -0,0 +1,150 @@
<?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 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");
}
}

View 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);
}
}

Binary file not shown.