Skip to main content

Utilisation de Copilot pour migrer un projet vers un autre langage de programmation

GitHub Copilot Chat peuvent vous aider à déplacer un projet vers un autre langage. Ce guide décrit ce qui est impliqué dans un processus de migration et donne un exemple de migration PHP vers Python.

Introduction

La migration d’un projet vers un nouveau langage de programmation peut être une tâche difficile et fastidieuse. GitHub Copilot peuvent vous aider à suivre ce processus en expliquant les modifications que vous devez apporter et suggérer du code de remplacement dans le nouveau langage.

Principes de migration d’un projet vers un nouveau langage

Tenez compte des points avant de démarrer un processus de migration :

  • Connaissances en codage

    Assurez-vous d’avoir une bonne compréhension des deux langages de programmation. Bien que Copilot puisse traduire du code pour vous, vous devez comprendre les choix qu’il propose et décider si vous souhaitez utiliser ses suggestions ou demander une autre suggestion.

  • Connaissance du système que vous migrez

    Veillez à comprendre l’architecture et la logique du système actuel, ainsi que les fonctionnalités et les caractéristiques qu’il offre aux utilisateurs. Vous devez être en mesure de vérifier que le code traduit effectue toutes les mêmes opérations que le code d’origine et produit les mêmes résultats.

  • Utiliser l’IA pour vous aider

    Si vous ne comprenez pas une partie particulière du code que vous êtes sur le point de traduire, utilisez la fonctionnalité « explication » de Copilot, soit sur l’ensemble du fichier, soit sur une partie sélectionnée du code dans un fichier. Consultez Poser des questions à GitHub Copilot dans votre IDE.

  • Planifier l’heure de fin de la migration

    La conversion est un processus en plusieurs étapes. Plus le projet que vous convertissez est important, plus vous devrez suivre d’étapes. Assurez-vous de prévoir suffisamment de temps pour terminer l’ensemble du processus.

  • Travailler de manière itérative

    Essayez de convertir des parties distinctes de votre projet séparément. Assurez-vous d’avoir vérifié toutes les modifications que vous avez apportées avant de passer à une autre partie du projet. Écrivez des tests pour les différentes parties du projet au fur et à mesure de votre progression afin de pouvoir confirmer que chacun des nouveaux composants fonctionne comme prévu.

  • Éviter d’introduire de la complexité dans le processus

    Dans un premier temps, vous devriez essayer de réaliser une conversion comparable. Cette opération ne sera pas possible pour l’ensemble du code de votre projet. Toutefois, pour éviter de compliquer la tâche de migration, vous devriez essayer de limiter le nombre de nouvelles modifications que vous introduisez, à l’exception de la traduction du code et de l’utilisation d’un nouveau framework et des dépendances appropriées.

  • Réaliser des tests de performance et refactoriser du code traduit

    Une fois la conversion initiale terminée et le système opérationnel, vous pouvez réaliser des tests de performance afin de comparer l’ancien et le nouveau système. Vous pouvez maintenant refactoriser le code dans le nouveau langage. C'est l’occasion d’optimiser le code et de réduire la dette technique.

Utilisation de Copilot afin de vous aider à migrer un projet vers un nouveau langage

En supposant que vous vous êtes déjà familiarisé avec le projet existant, un bon moyen de démarrer une migration consiste à ouvrir une branche du référentiel dans votre éditeur et de demander de l’aide à Copilot.

  1. Dans votre éditeur, ouvrez le panneau Copilot Chat. Consultez Poser des questions à GitHub Copilot dans votre IDE.

  2. Demandez à Copilot de décrire les étapes à suivre pour migrer le projet vers le nouveau langage.

    Par exemple, pour une migration de PHP vers Python, vous pouvez demander :

    @workspace I want to migrate this project from PHP to Python. Give me a high level overview of the steps I need to take. Don't go into detail at this stage.

    Note

    Le participant de conversation @workspace définit les fichiers dans l’espace de travail actuel comme contexte pour la question que vous posez.

    Copilot vous renverra généralement une liste des étapes à suivre pour migrer le projet.

  3. Copiez la réponse de Copilot et enregistrez-la quelque part pour pouvoir vous y référer tout au long du processus.

  4. Parcourez chaque étape du processus, en demandant une aide détaillée à partir de Copilot lorsque vous en avez besoin.

    Examinez attentivement chaque suggestion de Copilot. Assurez-vous de bien comprendre le code qu’il suggère et évaluez s’il est approprié pour votre projet. En cas de doute, demandez à Copilot de vous expliquer le code.

    Si vous pensez qu’une modification suggérée par Copilot n’est pas correcte d’une manière ou d’une autre, demandez une autre suggestion.

  5. Dès que vous avez migré un composant vers un état que vous pouvez exécuter, vérifiez qu’il fonctionne comme prévu. S’il génère une erreur, copiez-la dans la vue Copilot Chat et demandez à Copilot de vous aider à la corriger.

  6. Une fois la conversion initiale terminée, utilisez Copilot pour vous aider à refactoriser le code dans le nouveau langage. Pour plus d’informations, consultez « Refactorisation du code avec GitHub Copilot ».

Exemple : migration d’un projet PHP vers Python

L’exemple suivant décrit la migration d’une application web simple de PHP vers Python. Même si ce ne sont pas les langages de programmation que vous utilisez pour votre migration, vous trouverez peut-être utile de suivre les étapes décrites ici pour vous familiariser avec la migration d’un projet. Les étapes seront similaires pour migrer d’autres petits projets d’un langage à un autre.

Capture d’écran du « site web PHP simple » avant la migration de PHP vers Python.

Cet exemple se base sur les hypothèses suivantes :

  • Vous travaillez dans Visual Studio Code.
  • Les deux langages sont installés : PHP et la version 3.12 ou ultérieure de Python.

Migration d’un projet de site web simple

Nous allons migrer le code dans ce référentiel public sur GitHub : docs/simple-php-website.

Le référentiel se compose des fichiers suivants.

.gitignore
.htaccess
LICENSE
content
├── 404.phtml
├── about-us.phtml
├── contact.phtml
├── home.phtml
└── products.phtml
includes
├── config.php
└── functions.php
index.php
readme.md
template
├── style.css
└── template.php

Cet exemple fournit les prompts que vous pouvez entrer dans Copilot Chat pour terminer la migration et les réponses Copilot retournées pour une instance de cette migration. Les réponses Copilot Chat ne sont pas déterministes, vous obtiendrez donc probablement des réponses légèrement différentes de celles présentées ici.

Pendant un processus de migration, vous êtes susceptible d’obtenir des erreurs que vous devez corriger avant de poursuivre. Copilot peut vous aider pour cela. L’exemple contient quelques erreurs et montre comment Copilot peut vous aider à les corriger.

Les réponses que vous obtiendrez de Copilot Chat étant susceptibles d'être différentes de celles présentées ici, vous pouvez rencontrer des erreurs différentes. Vous trouverez donc peut-être plus facile de parcourir cet exemple de migration en utilisant les réponses indiquées ici, plutôt que celles que vous obtenez vous-même à partir de Copilot.

Après avoir terminé cet exemple de migration, vous pouvez utiliser la même méthodologie sur votre propre projet.

  1. Commencez par cloner une copie du référentiel sur votre ordinateur local.

  2. Exécutez l’application pour vérifier qu’elle fonctionne.

    Pour ce faire, dans un terminal, accédez à la racine du référentiel cloné et exécutez la commande suivante :

    Shell
     php -S localhost:8000
    

    Ensuite, dans un navigateur, accédez à : http://localhost:8000.

  3. Cliquez sur le site pour le découvrir et vérifier que la migration a été correctement effectuée.

  4. Créez une branche de travail dans votre référentiel et ouvrez-la en tant qu’espace de travail dans Visual Studio Code.

  5. Familiarisez-vous avec le contenu et l’architecture du projet existant. Copilot peut vous aider :

    1. Ouvrez la vue Copilot Chat.

    2. Entrez un prompt tel que :

      @workspace Describe this project in detail, explaining what the various components do and how they interact.

  6. Demandez Copilot pour obtenir une vue d’ensemble générale du processus de migration :

    @workspace I want to migrate this project from PHP to Python. Give me a high level overview of the steps I need to take. Don't go into detail at this stage.

    Copilot répondra par des instructions telles que :

    To migrate this project from PHP to Python, follow these high-level steps:
    
    1. Set Up Python Environment:
       - Install Python and set up a virtual environment.
       - Install necessary packages (e.g., Flask for web framework).
    
    2. Convert Configuration:
       - Translate the configuration settings from config.php to a Python configuration file.
    
    3. Rewrite Functions:
       - Convert PHP functions in functions.php to Python functions.
    
    4. Create Flask Application:
       - Set up a Flask application to handle routing and views.
       - Map the routes to corresponding views.
    
    5. Convert Templates:
       - Translate template.php to a Jinja2 template.
       - Update the CSS file path in the template.
    
    6. Convert Content Pages:
       - Convert .phtml content files to HTML or Jinja2 templates.
    
    7. Update .htaccess Rules:
       - Translate .htaccess rewrite rules to Flask route handling.
    
    8. Run and Test:
       - Run the Flask application and test all routes and functionalities.
       - Ensure the site works as expected and fix any issues.
    
    9. Documentation:
       - Update the readme.md with new instructions for running the Python project.
    
  7. Copiez la réponse Copilot et enregistrez-la quelque part pour pouvoir vous y référer tout au long du processus. Vous suivrez chacune de ces étapes en demandant de l’aide à Copilot au fur et à mesure.

  8. Si vous n’avez pas encore décidé quel framework Python vous souhaitez utiliser, vous pouvez demander conseil à Copilot :

    @workspace What Python frameworks can I use for this project once it is migrated to Python? Give me a selection of options, with a brief summary of the pros and cons of each in relation to this website project. Which framework would you recommend?

    Copilot répond par des informations sur différents frameworks, et conclut :

    For a project like yours - which is a simple, content-driven website - Flask is highly recommended. Its simplicity, flexibility, and ease of use (especially with its templating system that can easily replace your current PHP template structure) make it a great fit.
    

    Nous allons suivre les conseils de Copilot et utiliser Flask.

  9. Pour revenir à la vue d’ensemble générale de Copilot, la première étape consiste à configurer un environnement Python et à installer les packages nécessaires. Pour savoir comment procéder, dans Copilot Chat, entrez :

    @workspace I want to use Flask. Tell me how to set up a virtual environment and install the necessary packages.

    Copilot répondra par des instructions telles que :

    1. Create a virtual environment:
       - Open a terminal and navigate to your project directory.
       - Run the following command to create a virtual environment:
         python3 -m venv venv
    
    2. Activate the virtual environment:
       - On macOS and Linux:
         source venv/bin/activate
    
       - On Windows:
         venv\Scripts\activate
    
    3. Install Flask and necessary packages:
       - With the virtual environment activated, run the following command
         to install Flask and other necessary packages:
         pip install Flask
    
    4. Verify the installation:
       - You can verify that Flask is installed by running:
         pip list
    
  10. Suivez les instructions de Copilot et utilisez pip list pour vérifier que Flask est installé.

  11. Pour revenir à la vue d’ensemble de Copilot pour le processus de migration, l’étape suivante consiste à convertir la configuration. Demandez de l’aide à Copilot. Par exemple :

    @workspace As the first step in migrating this project from PHP to Python, create a Python configuration file by converting the functions in functions.php to Python functions. Tell me where to locate the Python config file in the project.

    Copilot suggère de créer un fichier appelé config.py dans le répertoire includes, contenant le code suivant.

    Python
    config = {
       'name': 'Simple Python Website',
       'site_url': '',
       'pretty_uri': False,
       'nav_menu': {
          '': 'Home',
          'about-us': 'About Us',
          'products': 'Products',
          'contact': 'Contact',
       },
      'template_path': 'template',
      'content_path': 'content',
      'version': 'v3.1',
    }
    
    def get_config(key=''):
       return config.get(key, None)
    
    def site_name():
       return get_config('name')
    
    def site_url():
       return get_config('site_url')
    
    def site_version():
       return get_config('version')
    
    def nav_menu(sep=' | '):
       nav_menu = ''
       nav_items = get_config('nav_menu')
    
       for uri, name in nav_items.items():
          query_string = request.args.get('page', '')
          class_active = ' active' if query_string == uri else ''
          url = f"{get_config('site_url')}/{'' if get_config('pretty_uri') or uri == '' else '?page='}{uri}"
    
          nav_menu += f'<a href="{url}" title="{name}" class="item{class_active}">{name}</a>{sep}'
    
       return nav_menu.strip(sep)
    
    def page_title():
       page = request.args.get('page', 'Home')
       return ' '.join(word.capitalize() for word in page.split('-'))
    
    def page_content():
       page = request.args.get('page', 'home')
       path = os.path.join(os.getcwd(), get_config('content_path'), f'{page}.phtml')
    
       if not os.path.exists(path):
          path = os.path.join(os.getcwd(), get_config('content_path'), '404.phtml')
    
       with open(path, 'r') as file:
          return file.read()
    
    def init():
       template_path = os.path.join(get_config('template_path'), 'template.html')
       with open(template_path, 'r') as file:
          return file.read()
    
  12. Créez le fichier includes/config.py et supprimez le fichier includes/config.php existant.

  13. Pour revenir à nouveau à la vue d’ensemble, demandez à Copilot de vous aider à réécrire les fonctions PHP.

    @workspace Continuing the migration of this project from PHP to Python, create Python functions to replace the existing PHP functions. Tell me where to locate the Python functions in the project.

    Copilot suggère de créer un fichier appelé functions.py dans le répertoire includes, contenant le code suivant.

    Python
    import os
    from flask import request
    from .config import get_config
    
    def site_name():
       return get_config('name')
    
    def site_url():
       return get_config('site_url')
    
    def site_version():
       return get_config('version')
    
    def nav_menu(sep=' | '):
       nav_menu = ''
       nav_items = get_config('nav_menu')
    
       for uri, name in nav_items.items():
          query_string = request.args.get('page', '')
          class_active = ' active' if query_string == uri else ''
          url = f"{get_config('site_url')}/{'' if get_config('pretty_uri') or uri == '' else '?page='}{uri}"
    
          nav_menu += f'<a href="{url}" title="{name}" class="item{class_active}">{name}</a>{sep}'
    
       return nav_menu.strip(sep)
    
    def page_title():
       page = request.args.get('page', 'Home')
       return ' '.join(word.capitalize() for word in page.split('-'))
    
    def page_content():
       page = request.args.get('page', 'home')
       path = os.path.join(os.getcwd(), get_config('content_path'), f'{page}.phtml')
    
       if not os.path.exists(path):
          path = os.path.join(os.getcwd(), get_config('content_path'), '404.phtml')
    
       with open(path, 'r') as file:
          return file.read()
    
    def init():
       template_path = os.path.join(get_config('template_path'), 'template.html')
       with open(template_path, 'r') as file:
          return file.read()
    
  14. Créez le fichier includes/functions.py et supprimez le fichier includes/functions.php existant.

  15. En continuant avec la vue d’ensemble, l’étape suivante consiste à créer une application Flask. Demandez à Copilot de vous aider :

    @workspace Set up a Flask application to handle routing and views, and map the routes to corresponding views. Tell me the location of any files that need to be created or changed.

    Copilot suggère de créer un fichier appelé app.py à la racine du projet, contenant le code suivant.

    Python
    from flask import Flask, render_template, request
    import os
    
    app = Flask(__name__)
    
    config = {
       'name': 'Simple Python Website',
       'site_url': '',
       'pretty_uri': False,
       'nav_menu': {
          '': 'Home',
          'about-us': 'About Us',
          'products': 'Products',
          'contact': 'Contact',
       },
       'template_path': 'template',
       'content_path': 'content',
       'version': 'v3.1',
    }
    
    def get_config(key=''):
       return config.get(key, None)
    
    @app.route('/')
    @app.route('/<page>')
    def index(page='home'):
       page_content = get_page_content(page)
       page_title = get_page_title(page)
       nav_menu = get_nav_menu()
       return render_template('template.html', page_title=page_title, page_content=page_content, nav_menu=nav_menu)
    
    def get_page_title(page):
       return ' '.join(word.capitalize() for word in page.split('-'))
    
    def get_page_content(page):
       path = os.path.join(os.getcwd(), get_config('content_path'), f'{page}.phtml')
       if not os.path.exists(path):
          path = os.path.join(os.getcwd(), get_config('content_path'), '404.phtml')
       with open(path, 'r') as file:
          return file.read()
    
    def get_nav_menu(sep=' | '):
       nav_menu = ''
       nav_items = get_config('nav_menu')
       for uri, name in nav_items.items():
          query_string = request.args.get('page', '')
          class_active = ' active' if query_string == uri else ''
          url = f"{get_config('site_url')}/{'' if get_config('pretty_uri') or uri == '' else '?page='}{uri}"
          nav_menu += f'<a href="{url}" title="{name}" class="item{class_active}">{name}</a>{sep}'
       return nav_menu.strip(sep)
    
    if __name__ == '__main__':
       app.run(debug=True)
    

    Copilot suggère également de renommer template/template.php par template/template.html et de mettre à jour le fichier pour utiliser la syntaxe de création de modèles Jinja2 :

    HTML
    
    <!DOCTYPE html>
    <html>
    <head>
       <meta charset="utf-8" />
       <meta http-equiv="x-ua-compatible" content="ie=edge"/>
       <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"/>
       <title>{{ page_title }} | {{ get_config('name') }}</title>
       <link href="{{ get_config('site_url') }}/template/style.css" rel="stylesheet" type="text/css" />
    </head>
    <body>
    <div class="wrap">
    
       <header>
          <h1>{{ get_config('name') }}</h1>
          <nav class="menu">
             {{ nav_menu|safe }}
          </nav>
       </header>
    
       <article>
          <h2>{{ page_title }}</h2>
          {{ page_content|safe }}
       </article>
    
       <footer>
          <small>&copy;{{ get_config('version') }} {{ get_config('name') }}.<br>{{ get_config('version') }}</small>
       </footer>
    
    </div>
    </body>
    </html>
    
    
  16. Créez les fichiers app.py et template/template.html comme suggéré.

  17. Copilot peut également suggérer qu’après avoir créé ces fichiers, vous devez maintenant exécuter python app.py dans le terminal, à partir de la racine du référentiel, puis naviguer jusqu’à http://127.0.0.1:5000.

    Note

    Selon la façon dont Python est installé sur votre ordinateur, vous devrez peut-être utiliser la commande python3 app.py au lieu de python app.py pour vous assurer que la bonne version de Python est utilisée.

    Lorsque vous effectuez cette opération, les messages d’erreur s’affichent dans le navigateur.

  18. Copiez le message d’erreur TemplateNotFound initial dans la vue Copilot Chat et demandez comment résoudre ce problème. Par exemple :

    @workspace When I run `python3 app.py`, I get the following error in the browser: `jinja2.exceptions.TemplateNotFound: template.html`. How can I fix this?

    Copilot répond que l’erreur indique que Flask n’est pas en mesure de localiser le fichier template.html.

    Il vous indique que, par défaut, Flask recherche des modèles dans un dossier nommé templates dans le répertoire racine de votre projet. Toutefois, votre fichier template.html se trouve dans le répertoire template. Pour résoudre ce problème, vous devez spécifier le dossier de modèle approprié lors de la création de l’application Flask. Il vous conseille de mettre à jour votre fichier app.py, en modifiant le app = Flask(__name__) de l’affectation pour inclure le paramètre template_folder :

    Python
    app = Flask(__name__, template_folder='template')
    
  19. En supposant que le serveur de développement Flask est toujours en cours d’exécution, si vous actualisez la page du navigateur à http://127.0.0.1:5000/, vous verrez maintenant une nouvelle erreur relative à la fonction get_config.

    Copiez ce message d’erreur dans la vue Copilot Chat et demandez de l’aide.

    @workspace When I run `python3 app.py`, I get the following error in the browser: `jinja2.exceptions.UndefinedError: 'get_config' is undefined.` How can I fix this?

    Copilot répond que l’erreur se produit, car get_config n’est pas disponible dans le contexte du modèle Jinja2. Il vous conseille d’ajouter le code suivant au fichier app.py, directement avant la ligne @app.route('/') :

    Python
    app.jinja_env.globals.update(get_config=get_config)
    
  20. Actualisez votre navigateur et vous devriez maintenant voir le site Web.

    Capture d’écran du « site web Python simple » sans style CSS.

    Toutefois, aucun des styles CSS n’est appliqué. Nous corrigerons cela ensuite.

  21. Demandez à Copilot :

    @workspace The deployed website does not use the CSS styles. How can I fix this?

    Copilot vous indique que Flask s’attend à ce que votre fichier CSS se trouve dans un répertoire appelé static. Il suggère de déplacer le fichier style.css existant du répertoire template vers un nouveau répertoire static, puis de mettre à jour le chemin d’accès au fichier style.css dans la partie head du fichier template.html. Modifiez comme suit :

    HTML
    
    <link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
    
    

    Lorsque vous actualiserez le navigateur, le site Web devrait maintenant s’afficher correctement.

    Pour terminer la migration initiale, continuez à suivre les étapes décrites dans la vue d’ensemble générale que Copilot vous a fournie, en demandant de l’aide si nécessaire.

Fin de la migration

Les prochaines étapes pour mener à bien le processus de migration consisteraient à :

  • Contrôler minutieusement la migration initiale.
  • Résoudre les bogues. Par exemple, dans l’exemple décrit ici, les liens de page ne fonctionnent actuellement que si vous définissez pretty_uri sur True dans la section config du fichier app.py. Si vous souhaitez pouvoir utiliser des paramètres de chaîne de requête dans les URL des pages, ou si vous souhaitez supprimer cette option du code, vous pouvez demander de l'aide à Copilot.
  • Écrire les tests pour le projet migré.
  • Nettoyer le projet en supprimant les fichiers qui ne sont plus nécessaires.
  • Refactoriser le code dans le nouveau langage. Le processus de migration a entraîné un projet Python dont l’architecture est basée sur celle du projet PHP d’origine. Après avoir effectué la migration initiale, vous pouvez maintenant refactoriser le code pour tirer le meilleur profit des fonctionnalités du langage Python et de l’infrastructure Flask.
  • Mise à jour de la documentation. Le fichier readme.md est maintenant obsolète et doit être réécrit.