DocScoDoc/docs/GuideDeveloppeurs.md
viennet 4948da5e84 - Documentattion du CAS;
- Remise en forme de plusieurs pages.
2023-03-01 19:05:21 +01:00

15 KiB
Raw Blame History

Documentation pour les développeurs ScoDoc

Informations pour les développeurs souhaitant étendre ou modifier ScoDoc.

Informations générales

Développer sur ScoDoc

Quelques conseils, indications et mémos pour les développeurs sur ScoDoc version 9.

Installation d'un serveur de développement

Quelques conseils pour configurer votre serveur de développement

Style et formatage du code

L'ancienneté de la base de code a rendu le style un peu incohérent, mais cela s'est nettement amélioré avec ScoDoc 9 (respect PEP 8).

Le code DOIT être formaté avec black avant tout commit (configurez votre éditeur pour appeler black à l'enregistrement).

Documentation

On pourra adopter le style "Google": https://google.github.io/styleguide/pyguide.html#383-functions-and-methods

Exemple: """Description résumée de la fonction

blah blah sur la fonction

Args:
    table_handle: An open smalltable.Table instance.
    keys: A sequence of strings representing the key of each table
      row to fetch.  String keys will be UTF-8 encoded.
    require_all_keys: Optional; If require_all_keys is True only
      rows with values set for all keys will be returned.

Returns:
    A dict mapping keys to the corresponding table row data
    fetched. Each row is represented as a tuple of strings. For
    example:

    {b'Serak': ('Rigel VII', 'Preparer'),
     b'Zim': ('Irk', 'Invader'),
     b'Lrrr': ('Omicron Persei 8', 'Emperor')}
"""

Git

Le dépôt est https://scodoc.org/git/viennet/ScoDoc

La branche master est celle de ScoDoc 9, d'où sont issues les paquets distribués (releases). Les développements ont lieu sur d'autres branches (api, dev92, entreprises, ...) avant d'être intégrés après tests. La branche Scodoc7 était l'ancienne (jusqu'à septembre 2021) version de ScoDoc.

Ci-dessous quelques pense-bête qui peuvent servir.

Hot fixes (internes)

Pour les développeurs internes (écriture sur le dépôt master), un exemple basique illustrant le cycle de développement:

# Créer une branche
#  si besoin (travail en cours), utiliser git stash avant
git checkout master
git branch hotfix
git checkout hotfix
... dev, test ...
git add ...
git commit -m "fixed ..."
git checkout master
git merge hotfix
git branch -d hotfix
# publication

# éventuellement: git stash pop

Dans la plupart des cas, on travaillera sur son propre dépôt (clone du dépt origine), et on proposera une pull request (PR, demande d'ajout en français).

Mettre à jour votre branche

Quand vous travaillez dans votre branche ma_branche, pour lui appliquer les mises à jour de master (remote), faire:

    git pull origin master

Commandes utiles, en vrac

  • git log -L:fonction_python:fichier.py
  • Commits locaux: git log @{u}..

Refactoring

Lint tous les fichiers modifiés:

    git status | grep modified | grep .py | awk '{print $2}' | xargs pylint -E

Affiche les variables non définies dans un fichier:

   pylint --disable=all  -e E sco_parcours_dut.py | grep undefined-variable | awk '{print $4;}' | sort | uniq | tr -d \' 

Prépare un sed pour renommer les variables non définies:

   for f in *.py
   do
   pylint --disable=all  -e E "$f" | grep undefined-variable | awk '{print "sed -i .bak s/"$4"/scu."$4"/ '$f'";}' | sort | uniq | tr -d \'
   done

Restore les modes au besoin (SAMBA les changent parfois):

    git diff -p -R --no-color | grep -E "^(diff|(old|new) mode)" --color=never | git apply

Note pour travailler sur VirtualBox:

addgroup scodoc vboxsf

Préparation d'une PR (Pull Request)

Principes généraux

Les remarques de cette section visent à obtenir une relecture facile de votre demande d'ajout (pull request, dite "PR"):

  • Éviter les modifications de forme qui ne changent pas le sens du code. L'utilisation de black est obligatoire : elle permet de normaliser la présentation du code. cela évite de générer des différences ne représentant que des changements de mise en forme (indentation, passages à la ligne). Cela évite aussi au développeur d'avoir à y réfléchir, autant de temps gagné !

  • Avoir un nombre d'étapes de validation faible (idéalement un seul commit pour les PR courantes - peu volumineuses).

  • La PR doit toujours être énoncée par rapport au dernier commit de la branche que vous visez (en général master du dépôt original).

Manipulations

Les manipulations sont décrites selon quatre phases du développement : l'installation, la mise en place, le suivi et la livraison.

l'installation

Il est pratique d'avoir en ligne les deux dépôts git distants que vous pouvez utiliser : votre dépôt personnel (https://scodoc.org/git/<user>/<dépôt>.git) et le dépôt officiel (https://scodoc.org/git/ScoDoc/ScoDoc.git).

pour ajouter une référence (et lui donner un nom) vers un dépôt distant, entrez la commande:

  git remote add nom_remote https://scodoc.org/git/ScoDoc/<dépôt>.git

Par la suite vous aurez donc une référence vers votre dépôt personnel (perso) et une référence vers le dépôt officiel (officiel). Si vous avez initialement cloné l'un des deux dépôts, la référence vers le dépôt d'origine existe et a pour nom origin.

La commande vous exposant tous les dépôts connus est :

  git remote -v

Mise en place

L'objectif de ce paragraphe est de créer une branche locale basée sur le master du dépôt officiel et bien sur de lui donner un nom.

pour cela (attention cela va écraser les éventuels fichiers modifiés. Si vous souhaitez conserver les modifications en cours, encadrez les lignes suivantes par git stash (avant) et git stash apply (après) :

  git reset --hard officiel/master
  git checkout -b ma_modif 

À partir de là, vous pouvez modifier, tester, développer et commit votre travail.

Suivi

Si votre développement prend plusieurs jours, il est probable que la branche principale évolue pendant ce temps.

Pour garder la cohérence, il est nécessaire de réintégrer en local les modifications de la branche principale. Ceci peut se faire de deux façons.

  • Une fusion (merge) applique toutes les modifications en un seul commit). C'est la méthode couramment utilisée.

  • Un rebase rejoue tous les commits de la nouvelle branche par dessus l'état le plus à jour de la branche principale (il en résulte un historique plus linéaire).

Les commandes git correspondantes :

  git fetch officiel
  git merge officiel/master

ou

  git fetch officiel
  git rebase officiel/merge

La livraison

Ça y est. Vous avez terminé le développement. IL n'y a plus qu'à demander l'intégration. Ceci se fait en plusieurs étapes (vous êtes bien sûr toujours sur la branche locale ma_modif et toutes vos modifications ont été commitées).

Étape 1 : faire l'inventaire des fichiers impliqués
  git fetch officiel/master
  git diff --name-only officiel/master
Étape 2 : passer black sur les fichiers modifiés

Cette étape est automatique avec les bons réglages sous VSCode (pas trouvé l'équivalent sous pyCharm).

À défaut les lignes suivantes réalisent le même travail :

  for fn in $(git diff --name-only officiel/master)
  do
    python3 -m black $fn
  done 

Faire une première lecture rapide pour vérifier qu'il ne reste pas de fichiers modifiés accidentellement.

Pour obtenir la modification sur un fichier spécifique (app/fichier.py par exemple):

  git diff officiel/master app/fichier.py

Utilisateurs Windows : Vérifiez bien que les réglages de fin de ligne suivent bien les règles Linux (pas de retour chariot (noté CR ou \r) en fin de ligne mais un seul caractère line feed (noté LF ou \n). Le cas échéant, réglez votre IDE pour cela.

À ce niveau là de la procédure, vous n'avez plus dans votre branche locale que les différences strictement nécessaires à votre correctif.

Étape 3 : résumez tous les commits depuis le point de divergence en un seul commit

Repérez le point de divergence de votre branche locale avec officiel/master (normalement git merge-base HEAD officiel/master)

Demander un rebase interactif depuis ce point :

  git rebase -i $(git merge-base HEAD officiel/master)

Explications: Le rebase interactif permet d'enregistrer un suite de manipulation de commit dans un seul fichier texte. Le fichier texte qui reprend tels quels tous les commits concernés (et donc qui ne fait rien) est préparé par la commande -i de la commande_ git rebase.

Vous pouvez ensuite modifier ce fichier dans votre éditeur favori (ou pas) (à régler par git config) pour décrire_ _votre intention (réordonner, changer le message, fusionner, ...) sur l'ensemble des commits.

Quand votre édition est terminée, git reprend la main est exécute chacune de vos opérations. Il est possible (bien que très rare) que des conflits apparaissent à ce moment-là. Les commandes habituelles de correction accompagnées des commandes :

git rebase --continue # pour poursuivre le processus
git rebase --abort # pour tout abandonner

vous permettront de résoudre ces problèmes exceptionnels.

Application:

git rebase -i $(git merge-base HEAD officiel/master)

Vous devez obtenir dans un éditeur de texte la liste des commits opéré depuis le début du développement sous cette forme (c'est un exemple : le nombre de lignes peut varier) :

pick eb8cbec modif 1
pick 83eb79e modif 2

# Rebase 5ffd074..83eb79e onto 5ffd074 (2 commands)
#
# Commands:
# p, pick <commit> = use commit
# r, reword <commit> = use commit, but edit the commit message
# e, edit <commit> = use commit, but stop for amending
# s, squash <commit> = use commit, but meld into previous commit
# f, fixup [-C | -c] <commit> = like "squash" but keep only the previous
#                    commit's log message, unless -C is used, in which case
#                    keep only this commit's message; -c is same as -C but
#                    opens the editor
# x, exec <command> = run command (the rest of the line) using shell
# b, break = stop here (continue rebase later with 'git rebase --continue')
# d, drop <commit> = remove commit
# l, label <label> = label current HEAD with a name
# t, reset <label> = reset HEAD to a label
# m, merge [-C <commit> | -c <commit>] <label> [# <oneline>]
# .       create a merge commit using the original merge commit's
# .       message (or the oneline, if no original merge commit was
# .       specified); use -c <commit> to reword the commit message
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
# However, if you remove everything, the rebase will be aborted.
#

Vous pouvez réorganiser tous les commits (changer l'ordre, fusionner) en changeant la commande pick au début de chaque ligne. L'idée ici est de fusionner toutes les lignes avec la première en remplaçant le 'pick' à partir de la ligne 2 par fixup. Optionnellement, vous pouvez reformuler le message de commit (commande reword sur la première ligne).

Vous construirez par exemple :

reword eb8cbec Correctif: Api - gestion des formation
fixup 83eb79e modif 2
...

Quand vous sortez de l'éditeur, git effectue toutes les opérations demandées.

À ce niveau-là de la procédure :

  • vous avez un seul commit pour l'ensemble du correctif proposé;

  • toutes les différences entre officiel/master et votre branche locale sont signifiantes.

Étape 4 :

Vous pouvez maintenant pousser votre branche locale sur votre dépôt personnel (vers une branche de même nom):

  git push --set-upstream perso ma_branche

Si vous avez déjà fait cette opération auparavant il est possible que le push soit refusé (car le rebase a modifié des commits qui avaient déjà été poussés). Dans ce cas l'option --force du push vous permette de passer outre, mais assurez-vous avant d'être le seul à travailler sur cette branche.

Etape 5 : La dernière étape se passe sur le site scodoc.org/git
  • Identifiez-vous

  • Placez-vous sur la branche nouvellement créée

  • À l'aide de l'interface du serveur, vous pouvez comparer l'état de votre branche par rapport au master officiel, et si cela vous convient, il vous reste à formuler une demande d'intégration (pull request). En remplissant les informations demandées.

Tests et tests unitaires

Voir TestsScoDoc

Cache Redis

Certains objets couteux à calculer sont cachés. Depuis ScoDoc 9, on utilise Redis, via flask-caching.

Au besoin, mémo:

  • client ligne de commande: https://redis.io/topics/rediscli

  • afficher les clés: redis-cli KEYS '*'

  • redis-cli TTL key affiche le TTL d'un clé, -1 si infini.

  • redis-cli -r -1 -i 3 KEYS '*_NT_*' surveille certaines clés (ici NT), affiche toutes les 3 secondes.

  • flask clear-cache efface le cache Redis.

Re-création du virtualenv

ScoDoc est livré avec un "virtualenv", qui contient tous les modules python nécessaires. Il se trouve sous /opt/scodoc/venv. Si vous souhaitez repartir de zéro, tester de nouvelles versions de certaines bibliothèques, ou autres expériences de ce genre, vous pouvez le récréer ainsi:

  # en tant qu'utilisateur scodoc
  cd /opt/scodoc
  /bin/rm -rf venv # ou mv ...
  python3 -m venv venv
  source venv/bin/activate
  pip install wheel

Puis soit vous installez les versions "officielles" (testées)

  pip install -r requirements-3.9.txt 

Soit vous prenez les versions les plus à jour disponibles. Une façon rapide de faire ceci est:

  cut -d= -f 1 requirements-3.9.txt | xargs pip install

à adapter selon vos objectifs.

Pour régénérer le fichier indiquant la liste des paquets:

  pip freeze > requirements-3.9.txt

Note: la mise à jour par apt recrée le virtualenv à chaque fois.

Roadmap

Sujets prioritaires en 2021-2022:

  • Modernisation du code: Flask, Python 3: achevé août 2021.

  • Prise en compte du Bachelor (BUT): SAÉ, suivi compétences, validations des blocs, UE, semestres selon la cadrage et l'arrêté Licence Pro 2020. (achevé avec ScoDoc 9.2 puis complété en 9.3 et 9.4)

  • Définition et développement nouvelle API (achevé avec 9.3 en juillet 22)

Autres sujets: