diff --git a/.pman.yml b/.pman.yml new file mode 100644 index 0000000..12513d0 --- /dev/null +++ b/.pman.yml @@ -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 diff --git a/bash/src/pman.conf.sh b/bash/src/pman.conf.sh index b1aec42..c33874c 100644 --- a/bash/src/pman.conf.sh +++ b/bash/src/pman.conf.sh @@ -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= diff --git a/bash/src/pman.sh b/bash/src/pman.sh index 8c12d1c..dcd9dfb 100644 --- a/bash/src/pman.sh +++ b/bash/src/pman.sh @@ -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" } ################################################################################ diff --git a/bin/_pman-composer_select_profile.php b/bin/_pman-composer_select_profile.php new file mode 100755 index 0000000..431259b --- /dev/null +++ b/bin/_pman-composer_select_profile.php @@ -0,0 +1,22 @@ +#!/usr/bin/php +selectProfile($profile, $config); +if (getenv("PMAN_COMPOSER_DEBUG")) { + $composer->print(); +} else { + $composer->write(); +} diff --git a/bin/pdev b/bin/pdev index 85106f0..6a2f5d1 100755 --- a/bin/pdev +++ b/bin/pdev @@ -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_ + AFTER_DELETE_ + AFTER_PUSH_ +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" diff --git a/bin/pman b/bin/pman index e97aae6..2c999e4 100755 --- a/bin/pman +++ b/bin/pman @@ -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" ;; diff --git a/bin/prel b/bin/prel index 28bc0f0..30a0706 100755 --- a/bin/prel +++ b/bin/prel @@ -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="$(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"); + } +} diff --git a/php/src/tools/pman/PmanYamlConfigFile.php b/php/src/tools/pman/PmanYamlConfigFile.php new file mode 100644 index 0000000..c0998dd --- /dev/null +++ b/php/src/tools/pman/PmanYamlConfigFile.php @@ -0,0 +1,57 @@ +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); + } +} diff --git a/sbin/composer.phar b/sbin/composer.phar deleted file mode 100755 index 7a44c36..0000000 Binary files a/sbin/composer.phar and /dev/null differ