Retour au cours

projet : application de to-do list en ligne de commande

Objectif du Projet

Mettre en pratique tout ce que nous avons appris (classes, tableaux, hashes, manipulation de fichiers, JSON) pour créer une application en ligne de commande fonctionnelle : une gestion de liste de tâches (To-do list).

Le Scénario

Nous allons créer un script todo.rb qui nous permettra de gérer nos tâches directement depuis le terminal. L’état de notre liste sera sauvegardé dans un fichier tasks.json pour que les données soient persistantes.

Fonctionnalités attendues

  • ./todo.rb list : Affiche toutes les tâches.
  • ./todo.rb add "Ma nouvelle tâche" : Ajoute une tâche à la liste.
  • ./todo.rb done <numéro> : Marque une tâche comme terminée.
  • ./todo.rb remove <numéro> : Supprime une tâche de la liste.

La Structure du Code

Pour bien organiser notre code, nous allons utiliser une classe TodoList qui encapsulera toute la logique.

Le Script Complet

Voici le code complet et commenté de notre application.

Fichier todo.rb :

#!/usr/bin/env ruby

require 'json'

# Le chemin vers notre fichier de sauvegarde
DB_FILE = 'tasks.json'

class TodoList
  def initialize
    # Charge les tâches depuis le fichier s'il existe, sinon initialise un tableau vide
    @tasks = File.exist?(DB_FILE) ? JSON.parse(File.read(DB_FILE)) : []
  end

  def add(task_description)
    # On ajoute un nouveau hash au tableau des tâches
    @tasks << { description: task_description, done: false }
    save
    puts "Tâche ajoutée : \"#{task_description}\""
  end

  def list
    puts "--- Votre liste de tâches ---"
    if @tasks.empty?
      puts "Aucune tâche pour le moment !"
    else
      @tasks.each_with_index do |task, index|
        status = task['done'] ? "[x]" : "[ ]"
        puts "#{index + 1}. #{status} #{task['description']}"
      end
    end
    puts "---------------------------"
  end

  def done(task_number)
    index = task_number - 1
    # On vérifie si la tâche existe
    if index < 0 || @tasks[index].nil?
      puts "Erreur : La tâche numéro #{task_number} n'existe pas."
    else
      @tasks[index]['done'] = true
      save
      puts "Tâche \"#{@tasks[index]['description']}\" marquée comme terminée."
    end
  end

  def remove(task_number)
    index = task_number - 1
    if index < 0 || @tasks[index].nil?
      puts "Erreur : La tâche numéro #{task_number} n'existe pas."
    else
      removed_task = @tasks.delete_at(index)
      save
      puts "Tâche \"#{removed_task['description']}\" supprimée."
    end
  end

  private

  # Méthode privée pour sauvegarder les tâches dans le fichier JSON
  def save
    File.write(DB_FILE, JSON.pretty_generate(@tasks))
  end
end

# --- Logique principale (le "routeur") ---

# ARGV est un tableau contenant les arguments passés au script
action = ARGV[0]
# ARGV[1..] récupère tous les arguments à partir du deuxième
arguments = ARGV[1..]

# On crée une instance de notre application
app = TodoList.new

case action
when 'list'
  app.list
when 'add'
  # On s'assure qu'il y a bien une description
  if arguments.empty?
    puts "Erreur : veuillez fournir une description pour la tâche."
  else
    app.add(arguments.join(' ')) # On rejoint les arguments pour former une phrase
  end
when 'done'
  app.done(arguments.first.to_i)
when 'remove'
  app.remove(arguments.first.to_i)
else
  puts "Action non reconnue. Actions disponibles : list, add, done, remove."
end

Comment l’utiliser ?

  1. Sauvegardez le code ci-dessus dans un fichier todo.rb.
  2. Rendez-le exécutable : chmod +x todo.rb.
  3. Utilisez-le :
    ./todo.rb add "Apprendre Ruby"
    ./todo.rb add "Créer une super application"
    ./todo.rb list
    ./todo.rb done 1
    ./todo.rb list
    ./todo.rb remove 2
    ./todo.rb list
  4. Observez le fichier tasks.json qui est créé et mis à jour dans le même dossier.

Bonnes Pratiques Mises en Œuvre

  • Encapsulation : Toute la logique est contenue dans la classe TodoList.
  • Persistance : L’utilisation de JSON pour sauvegarder l’état rend l’application persistante entre les exécutions.
  • Gestion des arguments : Le case à la fin du script agit comme un routeur qui appelle la bonne méthode en fonction de l’entrée de l’utilisateur.
  • Validation : Le code vérifie si les arguments sont présents et si les numéros de tâche sont valides.

Exercices et améliorations

  1. Ajouter une commande clear qui supprime toutes les tâches terminées.
  2. Utiliser la gem colorize pour afficher les tâches terminées en vert.
  3. Gérer les erreurs : Si l’utilisateur tape ./todo.rb done abc, la méthode .to_i renverra 0. Ajoutez une validation pour vous assurer que le numéro est bien un nombre supérieur à zéro.