---
# System prepended metadata

title: 'ITP3 - ECF #1'

---

# ITP3 - ECF #1

## Contexte

### Référentiels, compétences transversales
- Anglais
- Environnement de développement, Git, GitHub
- Rechercher de manière méthodique une solution à un problème
- Algorithmique
- Conception et programmation orientée objet
- Refactoring
- ...

### Niveau d'acquisition
- Soit imiter
- Soit adapter
- Soit transposer

> **Rappel** : compétence = savoirs + savoir-faire

### Modalités prédagogiques
- Travail et rendu individuels
- Chaque étape doit être validée avant de passer à la suivante

### Modalités d'évaluation
- Ça marche comme attendu
- Parler de son code, expliquer comment ça marche aurpès du formateur

### Livrables
- Repository GitHub privé

### Critères de performance
- Autonomie
- Lisibilité et maintenabilité du code
- KISS
- DRY

### Thèmatique
Vous devez concevoir et implémenter un CLI (Command Line Interpreter) en Java.

## Étapes

### Étape 1
- Mettre en place son environnement de développement
- Créer un nouveau workspace `simplon-p3-ecf`
- Créer un projet `simple-java-cli`, Maven, Java 17
- Créer une classe `Application` avec un main qui sysout "Hello world"
- Initialiser le projet avec Git et le partager dans un repository GitHub privé
- Ajouter Super Snippet en collaborateur

### Étape 2 - Qu'est-ce qu'un CLI ?
- L'objectif sera d'avoir un programme Java qui prend en entrée une ligne de commande, de l'interpréter pour en sortir un résultat
- Cette étape d'étude, d'analyse, devrait vous aider à concevoir le CLI...
- Faire une recherche et une synthèse en anglais de ce qu'est un CLI d'une manière générale
- Décrire avec plus de détails ce qu'est une ligne de commande, vocabulaire
- Partager cette synthèse, toujours en anglais, dans un README à la racine du repository
- Ajouter le ou les liens en anglais comme références
- Se limiter à 30 mn de recherche et 15 mn de synthèse

### Concevoir et implémenter un CLI

Contraintes et suggestions :
- La classe Application ne doit avoir qu'une seule méthode, la main, pour tester chaque commande, rien d'autre
- Toutes les commandes sont des méthodes séparées qui retournent toutes une chaîne de caractères (un résultat à afficher dans la console)
- Profiter de la première commande à implémenter pour faire une première proposition de conception pour le CLI. Même s'il n'y a pas d'UI (méthode main pour le moment), considérer qu'une ligne de commande est l'entrée du programme, l'interpréteur fait quelque chose avec cette commande, puis le programme affiche le résultat dans la console
- Une conception peut être revue comme le code, donc ne pas chercher quelque chose de complexe, rester simple, mais commencer à identifier des responsabilités

#### Commande `hw`
- Une commande qui permet d'afficher "Hello world!" dans la console

#### Commande `date`
- Une commande qui permet d'afficher la date actuelle au format ISO-8601

#### Commande `time`
- Une commande qui permet d'afficher l'heure actuelle au format ISO-8601

#### Commande `datetime`
- Une commande qui permet d'afficher la date et l'heure actuelles au format ISO-8601

#### Commande `print` et son alias/synonyme `echo`
- Une commande qui permet d'afficher un texte passé en argument
- Le texte peut être un ou plusieurs mots
- Si pas d'argument à la commande alors une ligne vide est imprimée
- Exemples: `echo Hello` > Hello, `print Hello world!` > Hello world!

#### Commande `secsanta`
- Une commande qui permet de générer des paires de noms aléatoirement à partir d'une liste en entrée
- Le séparateur de noms est la virgule
- Si pas d'argument à la commande, alors le message "Please provide a list of names to propose pairs from" est imprimé
- Si le nombre de noms n'est pas pair alors le message "Please provide an even number of names" est imprimé
- La sortie est les paires de noms séparés par :: et entourés de [], chaque paire séparée par un espace, les noms sont ceux donnés en entrée mais proposés aléatroirement
- Exemple: `secsanta Foo,Bar,Fiz,Biz` > [Foo::Biz] [Fiz::Bar]

#### Faire évoluer les commandes `date`, `time` et `datetime`
- Ces trois commandes peuvent avoir un paramètre optionnel pour indiquer le fuseau horaire souhaité, sans changer le format
- Ce paramètre est `--timezone=` suivi du nom du fuseau qui doit être dans la IANA Time Zone Database et être entre guillemets (exemple: `--timezone="Europe/Paris"`)
- Si une des commandes est utilisée sans le paramètre alors le comportement est le même qu'actuellement (fuseau par défaut)
- Si une des commandes est suivie d'un paramètre non reconnu alors le message "Did you mean --timezone= stupid idiot?" est affiché
- Si le paramètre est spécifié sans fuseau alors le message "Please specify a time zone name" est affiché
- Si le paramètre est spécifié mais avec un fuseau qui n'est pas entre guillemets alors le message "Please specify a time zone name between quotes" est affiché
- Si le paramètre est spécifié et valide mais avec un fuseau inconnu alors le message "Please specify a registered IANA time zone name" est affiché
- Exemples: `datetime --timezone="Europe/Paris"` > 2024-01-03T12:18:18.149326400, `datetime --timezone="America/New_York"` > 2024-01-03T06:18:18.149326400
- **Bonus** : utiliser une expression régulière "avancée" avec des captures de groupes [nommés](https://blog.mrhaki.com/2020/04/java-joy-using-named-capturing-groups.html) ou [pas](https://www.tutorialspoint.com/javaregex/javaregex_capturing_groups.htm).

### Étape 3 - Tester le CLI
- Ajouter JUnit dans les dépendances
- Écrire les tests unitaires pour l'ensemble de l'application sauf la classe Application (main)
- Tendre vers 100% de coverage, bien travailler les cas de tests, chercher à "faire planter" l'application en priorité pas de vérifier que ça marche...