Skip to main content

Uso de Copilot para migrar un proyecto a otro lenguaje de programación

GitHub Copilot Chat puede ayudarte a mover un proyecto a otro lenguaje. En esta guía se describe lo que implica un proceso de migración y se proporciona un ejemplo de una migración de PHP a Python.

Introducción

La migración de un proyecto a un nuevo lenguaje de programación puede ser una tarea difícil y lenta. GitHub Copilot puede ayudarte con este proceso explicando los cambios que necesitas realizar y sugiriendo código de reemplazo en el nuevo lenguaje.

Principios de migración de un proyecto a un nuevo lenguaje

Ten en cuenta los puntos antes de iniciar un proceso de migración:

  • Conocimientos de codificación

    Asegúrate de tener una buena comprensión de ambos lenguajes de programación. Aunque Copilot puede traducir código automáticamente, debes comprender las opciones que propone y decidir si deseas usar sus sugerencias o solicitar una sugerencia alternativa.

  • Conocimientos del sistema que vas a migrar

    Asegúrate de comprender la arquitectura y la lógica del sistema actual, además de las funciones y características que proporciona a los usuarios. Debes poder comprobar que el código traducido realiza todas las mismas operaciones que el código original y genera los mismos resultados.

  • Uso de la inteligencia artificial para ayudarte

    Si no entiendes una parte concreta del código que estás a punto de traducir, usa la característica "explicar" de Copilot, ya sea en todo el archivo o en una parte seleccionada del código dentro de un archivo. Consulta Preguntas sobre GitHub Copilot en el IDE.

  • Programar la hora de finalización de la migración

    La conversión es un proceso de varias fases. Cuanto mayor sea el proyecto que vas a convertir, mayor será el número de pasos que tendrás que realizar. Asegúrate de tener el suficiente tiempo para completar todo el proceso.

  • Trabajar iterativamente

    Intenta convertir partes discretas del proyecto por separado. Asegúrate de haber comprobado todos los cambios realizados antes de pasar a otra parte del proyecto. Escribe pruebas para las partes individuales del proyecto a medida que continúas para que puedas confirmar que cada uno de los nuevos componentes funciona según lo previsto.

  • Evitar la introducción de complejidad en el proceso

    Inicialmente, debes tener como objetivo realizar una conversión similar al original. Esto no será posible para todo el código del proyecto. Sin embargo, para evitar agregar complejidad a la tarea de migración, debes intentar limitar el número de cambios nuevos que se introducen, aparte de traducir el código y usar un nuevo marco y las dependencias adecuadas.

  • Prueba comparativa y refactorización del código traducido

    Una vez que hayas completado la conversión inicial y tengas un sistema funcional, puedes realizar pruebas comparativas para comparar los sistemas antiguos y nuevos. Ahora puedes refactorizar el código en el nuevo lenguaje. Esta es una oportunidad para optimizar el código y reducir la deuda técnica.

Uso de Copilot para ayudarte a migrar un proyecto a un nuevo lenguaje

Suponiendo que ya te has familiarizado con el proyecto existente, una buena manera de iniciar una migración es abrir una rama del repositorio en el editor y pedir ayuda a Copilot.

  1. En el editor, abre el panel de Copilot Chat. Consulta Preguntas sobre GitHub Copilot en el IDE.

  2. Pide a Copilot que describa los pasos que debes seguir para migrar el proyecto al nuevo lenguaje.

    Por ejemplo, para una migración de PHP a Python, podrías preguntar:

    @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

    El participante del chat @workspace establece los archivos en el área de trabajo actual como contexto de la pregunta que se formula.

    Copilot normalmente aportará una lista de pasos que debes realizar para migrar el proyecto.

  3. Copie la respuesta de Copilot y guárdala en algún lugar para consultarla durante el proceso.

  4. Sigue cada paso del proceso y solicita ayuda detallada de los datos Copilot según lo necesites.

    Considera cada sugerencia de Copilot cuidadosamente. Asegúrate de comprender el código que sugiere y evalúa si es adecuado para el proyecto. Si no estás seguro, pide a Copilot que te explique el código.

    Si crees que un cambio sugerido por Copilot no es correcto de alguna manera, solicita una sugerencia alternativa.

  5. En cuanto hayas migrado un componente a un estado que puedas ejecutar, comprueba que funciona según lo previsto. Si se genera un error, copia el error en la vista de Copilot Chat y pide a Copilot que te ayude a corregirlo.

  6. Una vez completada la conversión inicial, usa Copilot para ayudarte a refactorizar el código en el nuevo lenguaje. Para más información, consulta Refactorización de código con GitHub Copilot.

Ejemplo: migración de un proyecto PHP a Python

En el ejemplo siguiente se describe la migración de una aplicación web sencilla de PHP a Python. Incluso si no son los lenguajes de programación que usas para la migración, puede resultarte útil seguir los pasos descritos aquí para familiarizarte con una migración del proyecto. Los pasos serán similares para migrar otros proyectos pequeños de un lenguaje a otro.

Captura de pantalla del "sitio web de PHP simple" antes de la migración de PHP a Python.

En este ejemplo se da por supuesto que:

  • Trabajas en Visual Studio Code.
  • Tienes instalados ambos lenguajes: PHP y Python versión 3.12 o posterior.

Migración de un proyecto de sitio web sencillo

Vamos a migrar el código de este repositorio público en GitHub: docs/simple-php-website.

El repositorio consta de los siguientes archivos.

.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

En este ejemplo se proporcionan las indicaciones que puedes escribir en Copilot Chat para completar la migración y las respuestas de Copilot devueltas para una instancia de esta migración. Las respuestas de Copilot Chat no son deterministas, por lo que probablemente obtendrás respuestas ligeramente diferentes a las que se muestran aquí.

Durante un proceso de migración, es probable que obtengas errores que debes corregir antes de continuar. Copilot puede ayudarle con esto. En el ejemplo se incluyen algunos errores y se muestra cómo puedes hacer que Copilot te ayude a corregirlos.

Dado que es probable que las respuestas que obtengas de Copilot Chat sean diferentes a las que se muestran aquí, es posible que encuentres errores diferentes. Por lo tanto, es más fácil recorrer este ejemplo de migración mediante las respuestas que se muestran aquí, en lugar de las que obtienes de Copilot tú mismo.

Después de completar esta migración de ejemplo, puedes usar la misma metodología en tu propio proyecto.

  1. Empieza por clonar una copia del repositorio en el equipo local.

  2. Ejecuta la aplicación para comprobar que funciona.

    Para ello, en un terminal, ve a la raíz del repositorio clonado y ejecuta el siguiente comando:

    Shell
     php -S localhost:8000
    

    A continuación, en un explorador, ve a: http://localhost:8000.

  3. Haz clic en el sitio web para examinarlo, de modo que puedas comprobar que la migración se ha realizado correctamente.

  4. Crea una rama de trabajo en el repositorio y ábrela como una nueva área de trabajo en Visual Studio Code.

  5. Familiarízate con el contenido y la arquitectura del proyecto existente. Copilot puede ayudarle con esto:

    1. Abre la vista de Copilot Chat.

    2. Escribe una indicación como:

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

  6. Pregunta a Copilot para obtener información general de alto nivel del proceso de migración:

    @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 responderá con instrucciones como:

    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. Copie la respuesta de Copilot y guárdala en algún lugar para consultarla durante el resto de este proceso. Trabajarás en cada uno de estos pasos, solicitando a Copilot que te ayude a medida que progreses.

  8. Si aún no has decidido qué marco de Python deseas usar, puedes pedir a Copilot que te aconseje:

    @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 responde con información sobre varios marcos y concluye:

    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.
    

    Seguiremos los consejos de Copilot y usaremos Flask.

  9. De vuelta en la información general de alto nivel de Copilot, el primer paso es configurar un entorno de Python e instalar los paquetes necesarios. Para averiguar cómo hacerlo, en Copilot Chat, escribe:

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

    Copilot responderá con instrucciones como:

    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. Sigue las instrucciones de Copilot y usa pip list para comprobar que Flask está instalado.

  11. De vuelta en la información general de Copilot para el proceso de migración, el siguiente paso es convertir la configuración. Pregunta a Copilot para obtener ayuda con esto. Por ejemplo:

    @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 sugiere que crees un archivo denominado config.py en el directorio includes, que contiene el código siguiente.

    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. Cree el archivo includes/config.py y elimina el archivo includes/config.php existente.

  13. Vuelve a la información general de nuevo, pide a Copilot que te ayude a volver a escribir las funciones 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 sugiere crear un archivo denominado functions.py en el directorio includes, que contiene el código siguiente.

    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. Cree el archivo includes/functions.py y elimina el archivo includes/functions.php existente.

  15. Siguiendo con la información general, el siguiente paso es crear una aplicación de Flask. Pide a Copilot que te ayude con esto:

    @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 sugiere crear un archivo denominado app.py en la raíz del proyecto, que contiene el código siguiente.

    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)
    

    Copilottambién sugiere cambiar el nombre template/template.php a template/template.html y actualizar el archivo para usar la sintaxis de plantillas 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. Crea los archivos app.py y template/template.html como se sugiere.

  17. Copilot también puede sugerir que, después de crear estos archivos, ahora ejecutes python app.py en el terminal, desde la raíz del repositorio y, a continuación, vayas a http://127.0.0.1:5000.

    Note

    En función de cómo esté instalado Python en el equipo, es posible que tengas que usar el comando python3 app.py en lugar de python app.py para asegurarte de que se usa la versión correcta de Python.

    Al hacerlo, verás mensajes de error en el explorador.

  18. Copia el mensaje de error inicial TemplateNotFound en la vista de Copilot Chat y pregunta cómo puedes corregirlo. Por ejemplo:

    @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 responde que el error indica que Flask no puede localizar el archivo template.html.

    Indica que, de forma predeterminada, Flask busca plantillas en una carpeta denominada templates en el directorio raíz del proyecto. Sin embargo, el archivo template.html se encuentra en el directorio template. Para corregirlo, debes especificar la carpeta de plantilla correcta al crear la aplicación Flask. Te aconseja actualizar el archivo app.py y cambiar la asignación app = Flask(__name__) para incluir el parámetro template_folder:

    Python
    app = Flask(__name__, template_folder='template')
    
  19. Suponiendo que el servidor de desarrollo de Flask todavía se esté ejecutando, si actualizas la página del explorador en http://127.0.0.1:5000/, ahora verás un nuevo error relacionado con la función get_config.

    Copia este mensaje de error en la vista Copilot Chat y solicita ayuda.

    @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 responde que se produce el error porque get_config no está disponible en el contexto de plantilla Jinja2. Te aconseja agregar el código siguiente al archivo app.py, directamente antes de la línea @app.route('/'):

    Python
    app.jinja_env.globals.update(get_config=get_config)
    
  20. Actualiza el explorador y ahora deberías ver el sitio web.

    Captura de pantalla del "sitio web de Python simple" sin estilo CSS.

    Sin embargo, no se aplica ninguno de los estilos CSS. Lo corregiremos a continuación.

  21. Pregunta a Copilot:

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

    Copilot indica que Flask espera que el archivo CSS esté en un directorio denominado static. Sugiere mover el archivo style.css existente del directorio template a un nuevo directorio static y, a continuación, actualizar la ruta de acceso al archivo style.css dentro de la parte head del archivo template.html. Cambia esto a:

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

    Al actualizar el explorador, el sitio web ahora debería representarse correctamente.

    Para completar la migración inicial, sigue trabajando en los pasos descritos en la introducción general de alto nivel que Copilot te dio, solicitando ayuda cuando lo necesites.

Finalización de la migración

El trabajo adicional para completar correctamente el proceso de migración implicaría lo siguiente:

  • Comprobación exhaustiva de la migración inicial.
  • Corrección de errores. Por ejemplo, en la actualidad en el ejemplo descrito aquí, los vínculos de página solo funcionan si estableces pretty_uri en True en la sección config del archivo app.py. Si deseas usar parámetros de cadena de consulta en las direcciones URL de la página o si deseas quitar esta opción del código, puedes pedir a Copilot que te ayude a hacerlo.
  • Escribe pruebas para el proyecto migrado.
  • Limpia el proyecto, quita los archivos que ya no sean necesarios.
  • Refactoriza el código en el nuevo lenguaje. El proceso de migración ha dado lugar a un proyecto de Python cuya arquitectura se basa en la del proyecto PHP original. Después de realizar la migración inicial, ahora puedes refactorizar el código para aprovechar mejor las características del lenguaje Python y el marco de Flask.
  • Actualización de la documentación. El archivo readme.md ya no está actualizado y debe volver a escribirse.