Compare commits
	
		
			14 Commits
		
	
	
		
			829caf41a4
			...
			f1f033e0e9
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| f1f033e0e9 | |||
| 0cfad79ec0 | |||
| 8cfd803ead | |||
| d9989c6be7 | |||
| 7eb5efb421 | |||
| 92363cd543 | |||
| 3b379eb799 | |||
| c64b0801e2 | |||
| 745e5420df | |||
| 3d55e81899 | |||
| 0f4636fa77 | |||
| bbb55599f7 | |||
| 939f7726ab | |||
| 192a7f52c3 | 
							
								
								
									
										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 | ||||
| @ -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= | ||||
|  | ||||
| @ -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" | ||||
| } | ||||
| 
 | ||||
| ################################################################################ | ||||
|  | ||||
							
								
								
									
										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(); | ||||
| } | ||||
							
								
								
									
										10
									
								
								bin/pdev
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								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_<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" | ||||
|  | ||||
							
								
								
									
										42
									
								
								bin/pman
									
									
									
									
									
								
							
							
						
						
									
										42
									
								
								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" | ||||
|     ;; | ||||
|  | ||||
							
								
								
									
										23
									
								
								bin/prel
									
									
									
									
									
								
							
							
						
						
									
										23
									
								
								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="$(<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= | ||||
|  | ||||
| @ -2,7 +2,6 @@ | ||||
| namespace nulib\ext; | ||||
| 
 | ||||
| use Exception; | ||||
| use nulib\ext\json\JsonException; | ||||
| use nulib\file; | ||||
| use nulib\os\IOException; | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										150
									
								
								php/src/tools/pman/ComposerFile.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										150
									
								
								php/src/tools/pman/ComposerFile.php
									
									
									
									
									
										Normal 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"); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										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); | ||||
|   } | ||||
| } | ||||
										
											Binary file not shown.
										
									
								
							
		Reference in New Issue
	
	Block a user