Metadata-Version: 2.4
Name: xmlib-to-git
Version: 2.0.3
Summary: Génère un dépôt Git lisible depuis un export XML d'application Infinite Blue
Author-email: David Dessertine <david.dessertine@foederis.fr>
License-Expression: MIT
Keywords: infinite blue,rollbase,xml,git,export,low-code
Classifier: Development Status :: 5 - Production/Stable
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Software Development :: Version Control :: Git
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: lxml>=5.2
Requires-Dist: GitPython>=3.1.41
Requires-Dist: Unidecode>=1.3
Requires-Dist: Pillow>=10.3
Provides-Extra: completion
Requires-Dist: argcomplete; extra == "completion"
Provides-Extra: dev
Requires-Dist: pytest; extra == "dev"
Requires-Dist: build; extra == "dev"
Requires-Dist: twine; extra == "dev"
Requires-Dist: tomli; python_version < "3.11" and extra == "dev"
Dynamic: license-file

# XML Rollbase To GIT

Transforme un export XML d'application Rollbase / Infinite Blue en dépôt git lisible (Markdown, scripts,
HTML, fichiers décodés), un commit daté de l'export et un tag de version par génération.

### Fonctionnalités
- conversion de l'export XML en arborescence de fichiers (48 extracteurs, lecture en streaming : la
  mémoire ne dépend pas de la taille de l'export)
- historique git relatif à la date de création du fichier XML, tag de version
- push vers le dépôt distant (par défaut avec `-g`)
- création d'une branche par client avec le paramètre `-c` (table des clients fournie par `--customers-file`)

Architecture, extracteurs et ajout d'un élément : [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md). Éléments
de l'export non encore extraits : [docs/COVERAGE_GAPS.md](docs/COVERAGE_GAPS.md).

## Requires
Python 3.10 ou plus. Dépendances installées automatiquement : `lxml`, `GitPython`, `Unidecode`, `Pillow`
(voir `pyproject.toml`).

## Installation
`pip install xmlib-to-git` (ou `pip install --upgrade xmlib-to-git` depuis la 1.x)

Développement : `pip install -e ".[dev]"` puis `pytest`.

## Usage
```bash
$ xmlib-to-git \
    -f <fichier-xml> \
    -o <dossier-de-sortie> \
    -n <nom-de-l-application> \
    [-g <depot-distant-ssh> [-b <branche> | -c <id-client>] [--no-push]] \
    [--clean [--force-clean]] [-V]
```

`xmlib-to-git -h` détaille chaque option, avec des exemples. `-g` pousse par défaut (`--no-push` pour
seulement commiter et tagguer).

### Complétion des chemins dans le shell
Avec la forme collée (`-o/home/...`), le shell ne peut pas compléter le chemin : utiliser la forme
séparée (`-o /home/...`) ou `--out-folder=/home/...`. Pour activer la complétion des options et des
chemins (`-f`, `-o`) :

```bash
pip install "xmlib-to-git[completion]"          # ou : pip install argcomplete
eval "$(register-python-argcomplete xmlib-to-git)"   # à mettre dans ~/.bashrc
```

| Option | Rôle |
|---|---|
| `-f`, `--file` | export XML (obligatoire) |
| `-o`, `--out-folder` | dossier parent de la sortie (défaut : `.`) ; la sortie est écrite dans `<o>/<n>`, créé si besoin |
| `-n`, `--name` | nom du sous-dossier de sortie (obligatoire) |
| `-g`, `--git-repository-ssh` | dépôt git distant : initialise/récupère le dépôt, commite (daté de l'export), tague la version et **pousse** ; implique `--clean` |
| `--no-push` | avec `-g` : commite et tague sans pousser |
| `-b`, `--branch` | branche cible (défaut `master`), exclusif avec `-c` |
| `-c`, `--customer-id` | branche nommée d'après le client ; exige `--customers-file` |
| `--customers-file` | table des clients JSON `[{"id": 12, "name": "Nom du client"}]` (aucune table n'est livrée avec l'outil) |
| `--clean` | vide la sortie (hors fichiers cachés) avant la génération ; refusé pour `$HOME`, `/` ou un dossier non vide qui n'est ni un dépôt git ni une sortie de l'outil |
| `--force-clean` | autorise `--clean` sur un dossier non vide inconnu (jamais `$HOME` ni `/`) |
| `-V`, `--version` | affiche la version |

`python -m xmlib_to_git ...` est équivalent à `xmlib-to-git ...`. L'option `--push` de la 2.0.0 est toujours
acceptée mais n'a plus d'effet (`-g` pousse par défaut).

### Sécurité
- `-n` est un simple nom de dossier (ni chemin absolu, ni `..`, ni séparateur).
- `--clean` (implicite avec `-g`) ne vide jamais `$HOME`, ses parents ni `/`, ni un dossier non vide
  inconnu : un dossier est reconnu s'il est vide, s'il contient `.git`, ou s'il porte le marqueur
  `.xmlib-to-git` écrit à la fin de chaque export réussi (hors dépôt git). Sinon : erreur, sauf
  `--force-clean`.
- Avec `-g`, un dépôt existant dont l'`origin` n'est pas l'URL demandée est refusé (aucun push vers un
  autre dépôt).
- **Secrets** : avant le commit et le push, les fichiers générés sont analysés (jetons JWT, clés AWS,
  clés privées, littéraux `password`/`passwd`/`pwd`/`secret`/`api_key`/`token` entre guillemets, hors
  jetons de gabarit `{!#…}`). Les emplacements (`fichier:ligne` et nature, jamais la valeur) sont
  affichés sur la sortie d'erreur ; **le push n'est pas bloqué** : retirer le secret de l'application
  (et le révoquer) si l'alerte est fondée. `app.xml` (copie brute de l'export) n'est pas analysé : son
  contenu l'est dans les fichiers extraits.
- Noms issus de l'export (`..`, `.git`, `\`, caractères de contrôle, noms de plus de 200 octets) :
  remplacés par un nom sûr avec un avertissement ; images de champ limitées à PNG/JPEG/GIF/BMP.

### Migration depuis la 2.0.2
- Homonymes : le nom nu revient désormais à l'élément de plus petit `origId` (sinon `id`), quel que
  soit l'ordre du XML, et deux noms qui ne diffèrent que par la casse sont homonymes. Le premier export
  2.0.3 renomme une seule fois les groupes concernés (189 groupes, 1 756 fichiers sur l'export de
  référence) ; les exports suivants sont stables. Voir [docs/MIGRATION_DIFFS.md](docs/MIGRATION_DIFFS.md).
- Un export illisible (tronqué, mal formé, racine autre que `Application`) est refusé avant tout
  nettoyage ; un push refusé, un tag de version existant sur un autre contenu ou une identité git
  absente arrêtent l'export avec le code 2 (plus de faux succès).

### Migration depuis la 2.0.0
- Éléments homonymes (même nom sous le même parent) : le premier garde son chemin, les suivants sont
  écrits sous `<nom>~<origId>` au lieu d'écraser le premier ; le premier export 2.0.1 ajoute donc des
  fichiers (+4 463 sur l'export de référence). Voir [docs/MIGRATION_DIFFS.md](docs/MIGRATION_DIFFS.md).
- `-c` exige `--customers-file` (la table des clients n'est plus livrée).
- Un dossier de sortie 2.0.0 non vide sans `.git` n'a pas le marqueur : le premier `--clean` demande
  `--force-clean`.

### Migration depuis la 1.x
- `-g` pousse toujours par défaut, comme en 1.x : utilisez `--no-push` pour ne pas pousser.
- Le dossier de sortie `<o>/<n>` est créé automatiquement.
- `-c <id>` fonctionne (il était inutilisable en 1.x).
- Nouveaux fichiers générés (rôles, listes partagées, rapports, modèles d'interface, fichiers joints des
  graines `seeds/<objet>_files/`, etc.) : la première génération après la mise à jour produira donc un
  commit plus gros. Détail : [docs/MIGRATION_DIFFS.md](docs/MIGRATION_DIFFS.md).

## Développement
```bash
pip install -e . pytest
pytest
```
